方法一:使用dlopen打开库并使用dlsym调用动态库中函数
dll.c文件
#include
#include
int main()
{
void *libc=NULL;
void (*dll_x_printf)(char *str) = NULL;
char *err;
/* directly used function in libprintf.so, because we had linked */
//x_printf("direct used printf");
libc=dlopen("/home/wei.xuan/study/dll/libprintf.so", RTLD_NOW);
if (NULL != libc)
{
dll_x_printf=dlsym(libc, "x_printf");
if (NULL== dll_x_printf)
{
printf("can't find x_printf\n");
}
else
{
(*dll_x_printf)("hello, world\n")
}
dlclose(libc);
}
else
{
err=dlerror();
printf("libprintf.so failed! [%s]\n", err);
printf("open libprintf.so failed\n");
}
return 0;
}
libdll.c
#include
void x_printf(char *str)
{
if (NULL== str)
{
printf("string is null\n");
}
else
{
printf("%s\n", str);
}
return;
}
makefile
dll:dll.o libprintf.so
gcc -o dll dll.o -rdynamic -L. -ldl
dll.o:dll.c
gcc -c dll.c
libprintf.so:
gcc libdll.c -fPIC -shared -o libprintf.so
clean:
rm dll dll.o libprintf.so
文件dll.c中main函数调用libdll.c生成的so文件。
首先使用dlopen打开so库获取句柄,然后根据句柄调用dlsym获取想使用函数的地址,最后调用该函数。
这种方法在编译时不需要链接libprintf.so
方法二:编译时链接动态库
将makefile文件的dll:dll.o liprintf.so的指令该为
gcc -o dll dll.o -rdynmaic -L. -ldl -lprintf
如果makefile这么修改,则可在main中直接调用x_printf,即dll.c函数中注释部分。
注意:makefile命令libprinf.so生成时,不需要-c,如果命令如下:
gcc -c libdll.c -fPIC -shared -o libprintf.so,则执行时dlerror()会报错,错误如下:
libprintf.so: only ET_DYN and ET_EXEC can be loaded
修改动态链接库路径:
#sudo vim /etc/ld.so.conf 如下 ,增加/usr/local/lib
wayde@ubuntu:~$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
include /usr/local/lib
然后使用ldconfig重新加载配置文件