dynamic linking loader
dlopen
函数原型
void *dlopen(const char *filename, int flag);
dlerror
函数原型
char *dlerror(void);
dlsym
函数原型
void *dlsym(void *handle, const char *symbol);
dlclose
函数原型
int dlclose(void *handle);
写道
Since the value of the symbol could actually be NULL (so that a NULL return from dlsym() need not indicate an error), the correct way to test for an error is to call dlerror() to clear any old error conditions, then call dlsym(), and then call dlerror() again, saving its return value into a variable, and check whether this saved value is not NULL.
编写动态链接库
这里以这篇文章中”编写静态链接库“例子中的代码编译并生成动态链接库
写道
C: Linux C 编程 - 编写静态链接库
https://www.iteye.com/blog/lobin-2326336
https://www.iteye.com/blog/lobin-2326336
编译
# gcc -c qt.c -o qt.o
链接
# gcc -fPIC -shared qt.o -o libqt.so
调用
调用代码其实也是一样的
dynamic_lib_test.c
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include "qt.h" int main(int argc, char** argv) { int i; void *handle; void *fn; struct qt* (*qt)(int); int (*qt_get)(struct qt*); int (*qt_destroy)(struct qt*); handle = dlopen("./libqt.so", RTLD_NOW); if (handle == NULL) { printf("main: dlopen err.\n"); return -1; } dlerror(); fn = dlsym(handle, "qt"); if (dlerror()) { printf("main: dlsym err.\n"); return -1; } qt = fn; i = argc != 2 ? -1 : atoi(argv[1]); struct qt* v = qt(i); if (v == NULL) { return 1; } dlerror(); fn = dlsym(handle, "qt_get"); if (dlerror()) { printf("main: dlsym err.\n"); return -1; } qt_get = fn; printf("qt: i=%d\n", qt_get(v)); dlerror(); fn = dlsym(handle, "qt_destroy"); if (dlerror()) { printf("main: dlsym err.\n"); return -1; } qt_destroy = fn; qt_destroy(v); }
编译
# gcc -c dynamic_lib_test.c -o dynamic_lib_test.o
链接
# gcc dynamic_lib_test.o -o dynamic_lib_test -ldl
这里在链接的时候不需要指定要调用的链接库。
可以通过ldd查看下这个程序依赖的链接库:
# ldd dynamic_lib_test
linux-gate.so.1 => (0x008c3000)
libdl.so.2 => /lib/libdl.so.2 (0x001ad000)
libc.so.6 => /lib/libc.so.6 (0x006cf000)
/lib/ld-linux.so.2 (0x80081000)
可以看到这里没有链接libqt.so库。
运行
# ./dynamic_lib_test
qt: i=-1
# ./dynamic_lib_test 1413
qt: i=1413