Linux应用开发(1):Linux下链接动态库(.so)的方法

在Linux系统中开发应用时(C++),经常会遇到需要链接第三方库的情形。有些第三方库是系统默认存在的,有些是自行编译或设备厂商提供的,无论哪一种情况,都需要链接进应用中。

1. 链接动态库的方式

(1)指定链接路径,再指定链接库

格式:-L[lib_path] -l[lib_name]

-L用于指定动态库的存储路径,-l用于指定所要链接的动态库。

这一种情形通常用于动态库不存放于系统默认搜索路径(/usr/lib或usr/local/lib)的情况下。

如存在动态库/share/libabc.so,那么通过如下方式链接libabc.so动态库。

# -L/share -labc

注意-l后直接是abc,省略了lib和后缀.so,系统会自行查找。

(2)直接链接

格式:-l[lib_name]

当动态库直接存放于系统搜索路径下时,可直接链接,无需指定路径。

如/usr/lib/libabc.so可直接通过如下路径进行链接,无需指定路径。

-labc

(3)编译时,添加搜索路径

格式:-Wl, -rpath=[lib_path]

后续可直接指定-l[lib_name]

这种方式适用于不将第三方库放在系统默认搜索路径下,但又要统一管理第三方链接库的情形。

如创建了路径/share/libs/用于管理多个第三方库,路径下包含libabc.so,libedf.so等库。此时,可以首先在编译选项上添加搜索路径,之后可以直接链接内部所有库。

g++ ... -Wl, -rpath=/share/libs/ -labc -ledf

(4)通过环境变量添加搜索路径

通过在环境变量LD_LIBRARY_PATH中添加新的搜索路径,可以实现链接时通过直接链接库的目的。

(5)注册搜索路径(/etc/ld.so.conf)

前面提到系统有默认的链接库搜索路径,这个默认的搜索路径就是在/etc/ld.so.conf文件中指定的。开发者同样可以将其他路径添加为系统默认搜索路径。

通过如下两行制定添加默认搜索路径:

echo "/usr/local/lib64" >> /etc/ld.so.conf

ldconfig

(6)利用dl库导入

使用dl库导入动态库比较特殊,这种方式会从动态库中直接查找函数符号,并进行调用。

使用dl库导入动态链接库需要注意,如果是C++开发者,需要使用C语言将符号进行封装导出。

如下先将C++代码用C语言做二次封装

复制代码
#ifdef __cplusplus

extern "C"{

#endif


int StartCmdListen()

{

    MQTTCmd_ListenerTask& mqtt_listen = MQTTCmd_ListenerTask::getInstance();

    mqtt_listen.Start();

    return 0;

}

int StopCmdListen()

{

    MQTTCmd_ListenerTask& mqtt_listen = MQTTCmd_ListenerTask::getInstance();

    mqtt_listen.Stop();

    return 0;

}

#ifdef __cplusplus

}

#endif

然后再使用动态库进行导出

复制代码
    /** 导入库 */

    void* sln_node = dlopen("libabc.so", RTLD_LAZY);

    if (!sln_node) {

        return -1;

    }

    dlerror(); ///< 复位错误

    /** 导入Sln创建接口 */

    SlnCreate_t* SlnCreator = (SlnCreate_t*) dlsym(sln_node, "StartCmdListen"); ///< 加载外部符号

    if (!SlnCreator) {

        return -1;

    }

2. 库文件搜索路径

搜索的先后顺序是:

(1)编译目标代码时指定的动态库搜索路径;

(2)环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

(3)配置文件/etc/ld.so.conf中指定的动态库搜索路径;

(4)默认的动态库搜索路径/lib;

(5)默认的动态库搜索路径/usr/lib。

相关推荐
minji...16 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
w61001046617 小时前
cka-2026-ConfigMap
java·linux·cka·configmap
cc_yy_zh17 小时前
Win10 家庭版找不到Device Guard; 无法处理 VMware Workstation与Device Guard不兼容问题
linux·vmware
航Hang*17 小时前
VMware vSphere 云平台运维与管理基础——第2章(扩展):VMware ESXi 5.5 安装、配置与运维
运维·服务器·github·系统安全·虚拟化
嵌入式吴彦祖17 小时前
Luckfox Pico Ultra W WIFI
linux·嵌入式硬件
SPC的存折17 小时前
MySQL 8组复制完全指南
linux·运维·服务器·数据库·mysql
运维行者_17 小时前
OpManager MSP NetFlow Analyzer集成解决方案,应对多客户端网络流量监控挑战
大数据·运维·服务器·网络·数据库·自动化·运维开发
dashizhi201518 小时前
共享文件禁止拖动本地磁盘、共享文件禁止另存为、禁止打印共享文件、禁止复制共享文件的方法
运维·服务器·网络·安全·电脑
CoderCodingNo18 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
Linux技术芯19 小时前
Refault Distance算法详解
linux