Roslaunch 无法打开共享 object 文件:没有这样的文件或目录
Roslaunch cannot open shared object file: No such file or directory
我在使用 roslaunch
时打开共享库时遇到问题。
我有一个 ROS 包,其中包含包含以下行的 c++ 脚本:
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
无论如何我都会在标题中得到错误,即使我 运行 它来自那个库的文件夹。
此代码:
handle = dlopen("./rk4.so", RTLD_LAZY);
将成功当且仅当当前目录中有rk4.so
。特别是,它将忽略任何LD_LIBRARY_PATH
设置。
这是按设计工作的。
如果你想让dlopen
尊重LD_LIBRARY_PATH
,就改成这样:
handle = dlopen("rk4.so", RTLD_LAZY);
更好的方法是进行上述更改 和 通过在 link 时使用 -Wl,-rpath=/dir/where/rk4.so/is/installed
来避免设置 LD_LIBRARY_PATH
的需要申请。
我认为最便携的方法是 使用 ros::package::getPath("your_package_name")
向 dlopen
提供共享库文件的完整路径,如下所示(而不是修改 LD_LIBRARY_PATH
!)。这样您就可以轻松地在另一台计算机上获取您的包裹并运行!
将您的节点修改为 使用 ros/package.h
[=36 中的函数 ros::package::getPath
使用共享库的绝对路径加载共享库=] header:
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
以包含包含 ros::package::getPath
函数的 roslib
库 :
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})
我在使用 roslaunch
时打开共享库时遇到问题。
我有一个 ROS 包,其中包含包含以下行的 c++ 脚本:
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
无论如何我都会在标题中得到错误,即使我 运行 它来自那个库的文件夹。
此代码:
handle = dlopen("./rk4.so", RTLD_LAZY);
将成功当且仅当当前目录中有rk4.so
。特别是,它将忽略任何LD_LIBRARY_PATH
设置。
这是按设计工作的。
如果你想让dlopen
尊重LD_LIBRARY_PATH
,就改成这样:
handle = dlopen("rk4.so", RTLD_LAZY);
更好的方法是进行上述更改 和 通过在 link 时使用 -Wl,-rpath=/dir/where/rk4.so/is/installed
来避免设置 LD_LIBRARY_PATH
的需要申请。
我认为最便携的方法是 使用 ros::package::getPath("your_package_name")
向 dlopen
提供共享库文件的完整路径,如下所示(而不是修改 LD_LIBRARY_PATH
!)。这样您就可以轻松地在另一台计算机上获取您的包裹并运行!
将您的节点修改为 使用
ros/package.h
[=36 中的函数ros::package::getPath
使用共享库的绝对路径加载共享库=] header: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
以包含包含ros::package::getPath
函数的roslib
库 :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})