Linux下编写动态链接库的简单过程

来源:互联网 发布:淘宝代付超限怎么办 编辑:程序博客网 时间:2024/05/16 00:57

(1)       使用编译选项 -fPIC ,产生与位置无关的代码

(2)       使用编译选项 -fvisibility=hidden 隐藏符号

(3)       使用链接选项 -shared 表示生成动态链接库

(4)       使用链接选项 -wl 将参数传递给链接器

(5)       使用链接选项 -soname 指定库名,注意不是库文件名

(6)       保险起见,显式链接 C 库,即指定 -lc ,保证得到所需的启动代码,避免程序在有不兼容版本 C 库的系统上无法启动

(7)       为对外输出符号加上特殊声明, __attribute__((visibility("default")))

(8)       为了让 GCC 编译链接时能找到非默认路径下的动态链接库,在 /etc/profile 中添加 GCC 的 LIBRARY_PATH 环境变量

(9)       为了让程序运行时能自动找到非默认路径下的动态链接库,在 /etc/ld.so.conf 中添加路径,然后用 /sbin/ldconfig 更新缓存

(10)   例子:

a)         int func() __attribute__((visibility("default")));

b)        gcc –fPIC –fvisibility=hidden –g –c xxx.c –o xxx.o

c)        gcc –g –shared –Wl,-soname,libxyz.so –o libxyz.so.1.0 xxx.o

 

 

export LD_LIBRARY_PATH=thirdparty/lib   增加自己的 动态库路径


-fvisibility=default|internal|hidden|protected
gcc的visibility是说,如果编译的时候用了这个属性,那么动态库的符号都是hidden的,除非强制声明。



1.创建一个c源文件,内容简单
#include<stdio.h>
#include<stdlib.h>


__attribute ((visibility("default"))) void not_hidden ()
{
printf("exported symbol\n");
}

void is_hidden ()
{
printf("hidden one\n");
}

想要做的是,第一个函数符号可以被导出,第二个被隐藏。
先编译成一个动态库,使用到属性-fvisibility
gcc -shared -o libvis.so -fvisibility=hidden vis.c

现在查看
# readelf -s libvis.so |grep hidden
7: 0000040c    20 FUNC    GLOBAL DEFAULT   11 not_hidden
48: 00000420    20 FUNC    LOCAL  HIDDEN   11 is_hidden
51: 0000040c    20 FUNC    GLOBAL DEFAULT   11 not_hidden
可以看到,属性确实有作用了。

现在试图link
vi main.c
int main()
{
not_hidden();
is_hidden();
return 0;
}

试图编译成一个可执行文件,链接到刚才生成的动态库,
gcc -o exe main.c -L ./ -lvis
结果提示:

/tmp/cckYTHcl.o: In function `main':
main.c:(.text+0x17): undefined reference to `is_hidden'

说明了hidden确实起到作用了。

原创粉丝点击