赞
踩
在Linux系统中开发应用时(C++),经常会遇到需要链接第三方库的情形。有些第三方库是系统默认存在的,有些是自行编译或设备厂商提供的,无论哪一种情况,都需要链接进应用中。
格式:-L[lib_path] -l[lib_name]
-L用于指定动态库的存储路径,-l用于指定所要链接的动态库。
这一种情形通常用于动态库不存放于系统默认搜索路径(/usr/lib或usr/local/lib)的情况下。
如存在动态库/share/libabc.so,那么通过如下方式链接libabc.so动态库。
注意-l后直接是abc,省略了lib和后缀.so,系统会自行查找。
格式:-l[lib_name]
当动态库直接存放于系统搜索路径下时,可直接链接,无需指定路径。
如/usr/lib/libabc.so可直接通过如下路径进行链接,无需指定路径。
-labc
格式:-Wl, -rpath=[lib_path]
后续可直接指定-l[lib_name]
这种方式适用于不将第三方库放在系统默认搜索路径下,但又要统一管理第三方链接库的情形。
如创建了路径/share/libs/用于管理多个第三方库,路径下包含libabc.so,libedf.so等库。此时,可以首先在编译选项上添加搜索路径,之后可以直接链接内部所有库。
g++ ... -Wl, -rpath=/share/libs/ -labc -ledf
通过在环境变量LD_LIBRARY_PATH中添加新的搜索路径,可以实现链接时通过直接链接库的目的。
前面提到系统有默认的链接库搜索路径,这个默认的搜索路径就是在/etc/ld.so.conf文件中指定的。开发者同样可以将其他路径添加为系统默认搜索路径。
通过如下两行制定添加默认搜索路径:
echo “/usr/local/lib64” >> /etc/ld.so.conf
ldconfig
使用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;
-
- }
搜索的先后顺序是:
(1)编译目标代码时指定的动态库搜索路径;
(2)环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
(3)配置文件/etc/ld.so.conf中指定的动态库搜索路径;
(4)默认的动态库搜索路径/lib;
(5)默认的动态库搜索路径/usr/lib。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。