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})