问:我源文件为main.c, x.c, y.c, z.c,头文件为x.h,y.h,z.h,如何用gcc编译成.so动态链接库?
答:
#1. 生成动代连接库,假设名称为libtest.so
gcc x.c y.c z.c -fPIC -shared -o libtest.so
#2. 将main.c和动态连接库进行连接生成可执行文件
gcc main.c -L. -ltest -o main
#3. 输出LD_LIBRARY_PATH环境变量,以便动态库装载器能够找到需要的动态库
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
#4. 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
ldd main
# 执行就不用说了吧
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中
-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用/sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
下面用一个例子来具体说明:
1. 编辑要生成动态库的源文件sum.c
gcc -Wall -fPIC -O2 -c -o libsum.o sum.c //生成.o
gcc -shared -Wl,-soname,libsum.so -o libsum.so libsum.o //这步才生成共享库 .so 文
3. 怎么动态调用?
答:
#1. 生成动代连接库,假设名称为libtest.so
gcc x.c y.c z.c -fPIC -shared -o libtest.so
#2. 将main.c和动态连接库进行连接生成可执行文件
gcc main.c -L. -ltest -o main
#3. 输出LD_LIBRARY_PATH环境变量,以便动态库装载器能够找到需要的动态库
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
#4. 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
ldd main
# 执行就不用说了吧
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中
-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用/sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
下面用一个例子来具体说明:
1. 编辑要生成动态库的源文件sum.c
#include <stdio.h>
int sum(int a, int b)
{
return a + b; //功能很简单,就相加
}
2.现在准备生成一个名为 libsum.so 的目标本地库。使用 GCC 编译器来编译生成我们要的结果
gcc -Wall -fPIC -O2 -c -o libsum.o sum.c //生成.o
gcc -shared -Wl,-soname,libsum.so -o libsum.so libsum.o //这步才生成共享库 .so 文
3. 怎么动态调用?
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main(void)
{
void *handle;
int (*cosine)(int, int);
char *error;
handle = dlopen ("./libsum.so", RTLD_LAZY);
if (!handle)
{
fputs (dlerror(), stderr);
exit(1);
}
cosine = dlsym(handle, "sum");
if ((error = dlerror()) != NULL)
{
fputs(error, stderr);
exit(1);
}
printf ("%d\n", (*cosine)(4,5));
dlclose(handle);
return 0;
}