赞
踩
由于项目有涉及到源代码是否交付的选项,想着如果不交付源代码,那就得把程序封装好,但想着还是应该留一点开发空间给别人,所以就想着能不能把方法都变成动态链接库,只对其开放功能使用,不开放源代码编辑。
想着目前网上还没有详细介绍这一部分的内容,在之前自己摸索的经验传授给大家。
包的源代码链接可以点击这里。
在同一个文件夹下创建hello类文件,分别是hello.h和hello.cpp
hello.h
// // Created by dt on 2021/5/13. // #ifndef DYNAMIC_CONNECT_HELLO_H #define DYNAMIC_CONNECT_HELLO_H class fun{ public: int a; int b; //fun(int aa,int bb):a(aa),b(bb){}; fun(int aa,int bb); ~fun(); int add_a_b(); }; #endif //DYNAMIC_CONNECT_HELLO_H
hello.cpp
// // Created by dt on 2021/5/13. // #include "hello.h" int fun::add_a_b() { return this->a + this->b; } fun::fun(int aa, int bb) { this->a = aa; this->b = bb; } fun::~fun() { }
在该文件夹下,终端运行
g++ hello.cpp -fPIC -shared -o libhello.so
即可在该文件下获得libhello.so文件
-fPIC
:作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载其加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的
-shared
:产生一个共享对象,然后可以将其与其他对象链接以形成可执行文件。 并非所有系统都支持此选项。 为了获得可预测的结果,在指定此链接器选项时,还必须指定用于编译的相同选项集(-fpic,-fPIC或模型子选项)
-g
:令gcc生成调试信息,该选项可以利用操作系统的“原生格式(native format)”生成调试信息。GDB可以直接利用这个信息,其他调试器也可以使用这个调试信息
-c
:仅执行编译操作,不进行连接操作
-o
:指定生成的输出文件名称
在ros的工作空间,创建一个test的包,hello.h放在include/test目录下,libhello.so放在lib目录下(lib目录需要自行创建)。
test的src下需要创建main.cpp,代码如下
// // Created by dt on 2021/5/13. // #include "ros/ros.h" #include "std_msgs/String.h" #include <sstream> #include "dynamic_connect/hello.h" int main(int argc, char **argv) { ros::init(argc,argv,"h_learn"); ros::NodeHandle n; ros::Publisher pub = n.advertise<std_msgs::String>("listener",1000); ros::Rate loop_rate(10); //.so fun *f = new fun(4,2); int num2 = f->add_a_b(); delete f; f = NULL; while(ros::ok()) { std_msgs::String msg; std::stringstream ss; ss <<"Hello world " << num2; msg.data = ss.str(); ROS_INFO(msg.data.c_str()); pub.publish(msg); ros::spinOnce(); loop_rate.sleep(); } return 0; }
CMakeLists.txt如下
cmake_minimum_required(VERSION 3.0.2) project(dynamic_connect) find_package(catkin REQUIRED COMPONENTS roscpp rosmsg rospy ) catkin_package( # INCLUDE_DIRS include # LIBRARIES dynamic_connect # CATKIN_DEPENDS roscpp rosmsg rospy # DEPENDS system_lib ) include_directories( include ${catkin_INCLUDE_DIRS} ) link_directories( lib ${catkin_LIB_DIRS} ) add_executable(main src/main.cpp) target_link_libraries(main ${catkin_LIBRARIES} hello )
具体的修改地方如下
代码运行结果如下
[ INFO] [1620976666.758420253]: Hello world 6
[ INFO] [1620976666.858414282]: Hello world 6
[ INFO] [1620976666.958412370]: Hello world 6
[ INFO] [1620976667.058414110]: Hello world 6
[ INFO] [1620976667.158418228]: Hello world 6
[ INFO] [1620976667.258414183]: Hello world 6
[ INFO] [1620976667.358422537]: Hello world 6
[ INFO] [1620976667.458416599]: Hello world 6
其实使用动态链接库还是很简单的,只是以前没有接触过,所以还是对这里面的内容比较陌生,但真正做出来之后,其实发现世上的事情都正如卖油翁一样:“无他,但手熟尔。”
与诸君共勉。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。