当前位置:   article > 正文

【ROS】动态链接库(.so文件)的生成和调用

【ROS】动态链接库(.so文件)的生成和调用

【ROS】动态链接库(.so文件)的生成和使用

引言

由于项目有涉及到源代码是否交付的选项,想着如果不交付源代码,那就得把程序封装好,但想着还是应该留一点开发空间给别人,所以就想着能不能把方法都变成动态链接库,只对其开放功能使用,不开放源代码编辑。

想着目前网上还没有详细介绍这一部分的内容,在之前自己摸索的经验传授给大家。

包的源代码链接可以点击这里

1.生成so文件

在同一个文件夹下创建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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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() {

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在该文件夹下,终端运行

g++ hello.cpp -fPIC -shared -o libhello.so
  • 1

即可在该文件下获得libhello.so文件

-fPIC:作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载其加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的

-shared:产生一个共享对象,然后可以将其与其他对象链接以形成可执行文件。 并非所有系统都支持此选项。 为了获得可预测的结果,在指定此链接器选项时,还必须指定用于编译的相同选项集(-fpic,-fPIC或模型子选项)

-g:令gcc生成调试信息,该选项可以利用操作系统的“原生格式(native format)”生成调试信息。GDB可以直接利用这个信息,其他调试器也可以使用这个调试信息

-c:仅执行编译操作,不进行连接操作

-o:指定生成的输出文件名称

2.调用so文件

在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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

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
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

具体的修改地方如下

  1. include_directories 需要包含include文件夹;
  2. link_directories 需要添加lib路径,catkin_LIB_DIRS表示创建环境变量,${catkin_LIB_DIRS}为取该环境变量的值,lib是相对于当前软件包所在路径的相对路径;
  3. target_link_libraries :引用动态链接库,这里去掉lib前缀,去掉.so后缀,直接写hello

3.运行结果

代码运行结果如下

[ 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结语

其实使用动态链接库还是很简单的,只是以前没有接触过,所以还是对这里面的内容比较陌生,但真正做出来之后,其实发现世上的事情都正如卖油翁一样:“无他,但手熟尔。”

与诸君共勉。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/341911
推荐阅读
相关标签
  

闽ICP备14008679号