linux动态库与静态库混合连接 强烈推荐

在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库。使用方式为:
gcc test.cpp -L. -ltestlib

如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so。如果要指定为连接静态库则使用:

gcc test.cpp -L. -static -ltestlib

使用静态库进行连接。

2, 当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式。这时需要作用-Wl的方式:

gcc test.cpp -L. -Wl,-Bstatic -ltestlib -Wl,-Bdynamic -ltestlib

3, 另外还要注意系统的运行库使用动态连接的方式,所以当动态库在静态库前面连接时,必须在命令行最后使用动态连接的命令才能正常连接

,如:

gcc test.cpp -L. -Wl,-Bdynamic -ltestlib -Wl,-Bstatic -ltestlib -Wl,-Bdynamic

linux要使用pthread.h库时,文件编译的时候需要在末尾而且必须在末尾加上 –lpthread。

linux编程合并多个静态库.a为一个.a

.a 文件的结构和.tar文件就没有什么区别。 x 命令解出来, a 命令添加, t命令列表
假设A.a, B.a C.a 在/usr/local/lib目录下
mkdir /tmp/libABC
cd /tmp/libABC
ar x /usr/local/lib/A.a
ar x /usr/local/lib/B.a
ar x /usr/local/lib/C.a
ar cru libABC.a *.o
ranlib libABC.a

1、使用GCC创建和使用静态库

(1)gcc –o mylib.o –c mylib.c //生成o文件
(2)ar -rcs libmylib.a mylib.o //生成a文件
-c create的意思
-r replace的意思,表示当插入的模块名已经在库中存在,则替换同名的模块。
(3)cp libmylib.a /usr/lib/ //拷贝到默认目录
(4)编写程序使用库中的函数,需要包含相关的头文件,即可用下面的方式进行编译连接。
gcc –o test test.c -L. -lmylib
-L指定静态函数库的位置供查找,注意L后面还有’.',表示静态函数库在本目录下查找。
-l则指定了静态函数库名,由于静态函数库的命名方式是lib***.a,其中的lib和.a忽略。

2、使用GCC创建和使用动态库

(1)gcc –fPIC –o mylib.o –c mylib.c
gcc –shared –o libtt.so mylib.o
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
-shared 作用于链接阶段,实际传递给链接器ld,让其添加作为共享库所需要的额外描述信息,去除共享库所不需的信息。
(2)也可以直接使用下面一条命令:
gcc –fPIC –shared –o libtt.so mylib.c
(3)将动态库拷贝到linux 的标准库中,usr/local/lib 或者/usr/lib 或者/lib,使用ldconfig命令加载
cp libttt.so /usr/local/lib
(4) 编译src 程序使用动态库,隐式调用方法: 在编译调用库函数代码时指明动态库的位置及名字
gcc –o test test.c ./usr/lib/libttt.so
(5)编译src程序使用动态库,显示调用方法
显式调用动态库需要四个函数的支持, 函数 dlopen 打开动态库, 函数 dlsym 获取动态库中对象基址, 函数 dlerror 获取显式动态库操作中的错误信息, 函数 doclose 关闭动态库.

#include <dlfcn.h>
int main()
{
void *pHandle;
void (*pFunc)(); // 指向函数的指针
int p;
pHandle = dlopen(“./d1.so”, RTLD_NOW); // 打开动态库
if(!pHandle){
printf(“Can’t find d1.so \n”);
exit(1);
}
pFunc = (void (
)())dlsym(pHandle, “print”); // 获取库函数 print 的地址
if(pFunc)
pFunc();
else
printf(“Can’t find function print\n”);
dlclose(pHandle); // 关闭动态库
return 0;
}
gcc –o test test.c -lttt -L
此时会到系统目录下去搜素libttt.so文件,具体搜索方法见下一节。

3、shell 搜索动态库路径位置的两种方法
(1) 使用命令导入动态库的路径,命令如下:
export LD_LIBRARY_PATH=dir (如/usr/local/lib)
(2) 在/etc/ld.so.conf 文件中更增加一条,修改后用ldconfig 命令载入修改。

4、其他

(1)ldd命令可以查看一个可执行程序依赖的共享库,
# ldd /bin/ln
=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2
=> /lib/ld- linux.so.2 (0×40000000)
可以看到ln命令依赖于libc库和ld-linux库

(2)看动态库包含哪些定义用:
nm -D lib*.so

(3)当生成动态库时,源文件又引用其他静态库,需要一起写。这时源文件里面不用用extern f();,这样就不能引入静态库。需要直接#include 头文件。

 比如,gcc -fexceptions -O2 -o hello.node ./build/Release/obj.target/hello/hello.o ./libpanda.a /usr/local/lib/libnfc.a  -shared -fPIC

https://www.cnblogs.com/bigben0123/p/3304863.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值