I'm having problems with opening a shared library when using roslaunch
.
I have a ROS package with a c++ script containing the line:
handle = dlopen("./rk4.so", RTLD_LAZY);
This shared library resides inside my ROS package. I managed to build the package with catking build, having in my CMakeLists.txt the lines
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}
)
The problem is when I try to run my executable. Since the library is not in a folder where libraries usually are, I added the path to that folder to LD_LIBRARY_PATH
and exported it.
However I don't understand why I don't get the error in the title only when I use rosrun
while I'm inside the exact folder in which the library is.
My issue is that I want to launch that node with a launch file, but using roslaunch
I get the error in the title anyway, even if I run it from inside the folder of that library.
I think the most portable way of doing so is to supply dlopen
with the full path to the shared library file by using ros::package::getPath("your_package_name")
as follows (and not modifying LD_LIBRARY_PATH
!). This way you can easily get your package up and running on another computer!
Modify your node to load the shared library using the absolute path to the shared library by using the function ros::package::getPath
from the ros/package.h
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);
This for example would be a minimal working example for a node 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;
}
Modify your CMakeLists.txt
to include the roslib
library which contains the ros::package::getPath
function:
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})