定义两个包,mylib mynode ,mylib 创建.so文件,mynode调用.so文件定义的东西
项目开源地址如下
GitHub - yusongmin1/my.so: make a .so file and use it in ros2
具体目录如下
通过如下命令创建这两个包,cmakelist.txt也跟着生成成功。
ros2 pkg create --build-type ament_cmake --dependencies rclcpp rclpy std_msgs --node-name mycpp mynode
ros2 pkg create --build-type ament_cmake --dependencies rclcpp rclpy std_msgs --node-name myclass mylib
myclass.hpp 定义了一个类和一个函数,
#ifndef MY_CLASS_HPP
#define MY_CLASS_HPP
#include<iostream>
class MYCLASS{
public:
int a;
int b;
MYCLASS(int a,int b);
~MYCLASS();
int MYCLASS_ADD();
};
void print_myclass()
{
std::cout<<"我创建的.so文件输出东西了\n";
}
#endif //MY_CLASS_HPP
myclass.cpp 类的初始化和函数定义
#include "mylib/myclass.hpp"
int MYCLASS::MYCLASS_ADD() {
return this->a + this->b;
}
MYCLASS::MYCLASS(int a, int b) {
this->a = a;
this->b = b;
}
MYCLASS::~MYCLASS() {
std::cout<<"cnmcnmcnmcncmcnmccnm\n";
}
int main(int argc, char ** argv)
{
(void) argc;
(void) argv;
;
}
创建.so文件有两种使用方式,第一种:生成.so文件,保留.hpp文件,把这两个文件放到所需要使用这个.so文件的包里,第二种,导出成一个库,然后用类似
find_package(ament_cmake REQUIRED)这种指令调用。
第一种方式,对应开源地址里的first分支
mylib包里的 cmakelist.txt修改如下,其中不加注释的就是默认生成的代码,了解即可
cmake_minimum_required(VERSION 3.8)
project(mylib)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
find_package(std_msgs REQUIRED)
add_library(myclass SHARED src/myclass.cpp)#生成.so文件
# add_executable(myclass src/myclass.cpp)
target_include_directories(myclass PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}>)#包含include目录
target_compile_features(myclass PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
ament_target_dependencies(
myclass
"rclcpp"
"rclpy"
"std_msgs"
)
install(DIRECTORY include/
DESTINATION include
)#把include文件夹复制到install目录
install(TARGETS myclass
DESTINATION lib)#把.so文件安装到安装目录
# # Export CMake configuration
# ament_export_include_directories(include)
# ament_export_libraries(myclass)
ament_package()
安装目录出现如下东西就算成功了
将这两个东西复制到要用到.so文件的mynode目录下,
变成这样就可以了
mycpp.cpp文件如下,非常简单,有手就行,注意!!!! 不要忘记包含.so文件的头文件
#include "rclcpp/rclcpp.hpp"
#include "mynode/myclass.hpp"
int main(int argc, char **argv)
{
rclcpp::init(argc,argv);
auto node_=std::make_shared<rclcpp::Node>("mynode");
MYCLASS* myclass=new MYCLASS(1,1);
while (rclcpp::ok())
{
std::cout<<"开始使用类了"<<myclass->MYCLASS_ADD()<<"\n";
myclass->a++;
sleep(1);
}
return 0;
rclcpp::shutdown();
}
cmakelist.txt 如下
cmake_minimum_required(VERSION 3.8)
project(mynode)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
add_executable(mycpp src/mycpp.cpp)
target_include_directories(mycpp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)#包含include目录
ament_target_dependencies(
mycpp
rclcpp
)#不可或缺添加
install(DIRECTORY include/
DESTINATION include
)#把include文件夹复制到install目录
install(FILES
lib/libmyclass.so
DESTINATION lib
)#.so文件复制到安装目录
target_link_libraries(mycpp ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmyclass.so)#链接.so库文件
install(TARGETS mycpp
DESTINATION lib/${PROJECT_NAME})
ament_package()
colcon build ,source 一下
第一种方式就算完成了
第二种方式对应开源地址里的master分支,这个分支需要先编译mylib ,然后source 一下才可以编译mynode,否则报错。克隆命令
git clone -b master git@github.com:yusongmin1/my.so.git
colcon build --packages-select mylib
source ./install/local_setup.bash
colcon build --packages-select mynode
mycpp.cpp需要更改包含的头文件,具体如下
#include "mylib/myclass.hpp"
两个包的cmakelist.txt 需要修改
mylib的,注意这里导出的库文件名称应和工程名称一致project(mylib),主要部分就是不可删除的那两部分
cmake_minimum_required(VERSION 3.8)
project(mylib)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
find_package(std_msgs REQUIRED)
add_library(mylib SHARED src/myclass.cpp)#生成.so文件
# add_executable(mylib src/mylib.cpp)
target_include_directories(mylib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}>)#包含include目录
target_compile_features(mylib PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
ament_target_dependencies(
mylib
"rclcpp"
"rclpy"
"std_msgs"
)
install(DIRECTORY include/
DESTINATION include
)#把include文件夹复制到install目录
# Install library 必须有,不可删除
install(TARGETS mylib
EXPORT export_mylib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
)
# # Export CMake configuration 必须有,不可删除
ament_export_include_directories(include)
ament_export_libraries(mylib)
ament_package()
导出库的基准,都这么写
# Install library 必须有,不可删除
install(TARGETS mylib
EXPORT export_mylib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
)
使用ament_export_include_directories
来导出头文件目录,这样其他包可以通过find_package
找到并包含这些头文件。使用ament_export_libraries
来导出你的库文件。
# # Export CMake configuration 必须有,不可删除
ament_export_include_directories(include)
ament_export_libraries(mylib)
mynode 的cmakelist.txt
cmake_minimum_required(VERSION 3.8)
project(mynode)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(mylib REQUIRED)#包含生成的库文件
add_executable(mycpp src/mycpp.cpp)
target_include_directories(mycpp PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)#包含include目录
ament_target_dependencies(
mycpp
rclcpp
mylib#包含生成的库文件
)#不可或缺添加
install(DIRECTORY include/
DESTINATION include
)#把include文件夹复制到install目录
install(TARGETS mycpp
DESTINATION lib/${PROJECT_NAME})
ament_package()
注意两点 find_package(mylib REQUIRED)#包含生成的库文件,
ament_target_dependencies(
mycpp
rclcpp
mylib#包含生成的库文件
)#不可或缺添加