Roslaunch 无法打开共享对象文件:没有这样的文件或目录
Posted
技术标签:
【中文标题】Roslaunch 无法打开共享对象文件:没有这样的文件或目录【英文标题】:Roslaunch cannot open shared object file: No such file or directory 【发布时间】:2021-06-04 12:43:10 【问题描述】:我在使用roslaunch
时打开共享库时遇到问题。
我有一个带有 c++ 脚本的 ROS 包,其中包含以下行:
handle = dlopen("./rk4.so", RTLD_LAZY);
这个共享库位于我的 ROS 包中。我设法用 catking build 构建了这个包,在我的 CMakeLists.txt 中有这些行
add_library(RK4 SHARED IMPORTED)
set_target_properties(RK4 PROPERTIES IMPORTED_LOCATION $CMAKE_CURRENT_SOURCE_DIR/src/SharedLibs/rk4.so)
target_link_libraries(simulator_node
RK4
$CMAKE_DL_LIBS
$catkin_LIBRARIES
)
问题是当我尝试运行我的可执行文件时。由于该库不在库通常所在的文件夹中,因此我将该文件夹的路径添加到LD_LIBRARY_PATH
并将其导出。
但是我不明白为什么只有当我在库所在的确切文件夹中使用rosrun
时才在标题中出现错误。
我的问题是我想使用启动文件启动该节点,但使用 roslaunch
无论如何我都会在标题中收到错误,即使我从该库的文件夹中运行它也是如此。
【问题讨论】:
你不能把ros::package::getPath("your_package_name")
添加到dlopen
中的目录吗?
@2b-t 你是什么意思?你能更明确地解释一下吗? (对不起,我是初学者)
我的意思是dlopen
将filename
作为第一个参数。使用ros::package::getPackage("your_package_name")
,您可以获得包的目录。如果您的 ROS 包如您所述位于您的包目录中,那么您应该能够将其组合到像 handle = dlopen(ros::package::getPackage("your_package_name") + "/rk4.so", RTLD_LAZY);
这样的绝对文件路径。我不确定这是否能解决您的问题,因为我还没有机会对其进行测试。
刚刚对其进行了测试,如果您考虑从 std::string
到 char const*
的转换(请参阅下面的答案),它可以工作。 我不建议您修改LD_LIBRARY_PATH
,因为它是一个环境变量。相反,请尽量让您的修改保持可移植性。
【参考方案1】:
我认为这样做最便携的方法是使用ros::package::getPath("your_package_name")
向dlopen
提供共享库文件的完整路径,如下所示(而不是修改LD_LIBRARY_PATH
!) .这样您就可以轻松地在另一台计算机上启动并运行您的程序包!
修改您的节点以使用ros/package.h
标头中的函数ros::package::getPath
使用共享库的绝对路径加载共享库:
std::string const library_path = ros::package::getPath("your_package") + "/relative/path/to/libyourlib.so";
auto* handle = ::dlopen(library_path.c_str(), RTLD_LAZY);
例如,这将是节点 your_node
的最小工作示例:
#include <cstdlib>
#include <iostream>
#include <string>
#include <dlfcn.h>
#include <ros/ros.h>
#include <ros/package.h>
int main (int argc, char** argv)
ros::init(argc, argv, "your_node");
ros::NodeHandle n;
std::string const package_path = ros::package::getPath("your_package");
std::string const library_path = package_path + "/src/libyourlib.so";
auto* handle = ::dlopen(library_path.c_str(), RTLD_LAZY);
if (!handle)
std::cerr << "Error: could not load shared library!" << std::endl;
else
std::cout << "Library successfully loaded!" << std::endl;
return EXIT_SUCCESS;
修改您的 CMakeLists.txt
以包含 roslib
库,其中包含 ros::package::getPath
函数:
find_package(catkin REQUIRED COMPONENTS
roscpp
roslib
)
include_directories(
$catkin_INCLUDE_DIRS
)
add_executable(your_node src/your_node.cpp)
target_link_libraries(your_node $catkin_LIBRARIES $CMAKE_DL_LIBS)
【讨论】:
【参考方案2】:这段代码:
handle = dlopen("./rk4.so", RTLD_LAZY);
将成功当且仅当当前目录中有rk4.so
。特别是,它将忽略任何LD_LIBRARY_PATH
设置。
这是按设计工作的。
如果您希望 dlopen
尊重 LD_LIBRARY_PATH
,请像这样更改:
handle = dlopen("rk4.so", RTLD_LAZY);
更好的方法是进行上述更改并避免在应用程序链接时使用-Wl,-rpath=/dir/where/rk4.so/is/installed
来设置LD_LIBRARY_PATH
。
【讨论】:
以上是关于Roslaunch 无法打开共享对象文件:没有这样的文件或目录的主要内容,如果未能解决你的问题,请参考以下文章
加载共享库时出错:libgmock.so:无法打开共享对象文件:没有这样的文件或目录
libarb.so:无法打开共享对象文件:没有这样的文件或目录
加载共享库时出错:libgfortran.so.1:无法打开共享对象文件:没有这样的文件或目录
libcrypto.so.10:无法打开共享对象文件:没有这样的文件或目录