C语⾔和python调⽤.so⽂件什么是静态库和动态库, 看⼀篇博客
现在,我们⾸先⽣成.so⽂件
⾸先, 我们写⼀个a.c⽂件
1 2 3 4 5 6 7 8 9#include <stdio.h>
void show() {
printf("this is a test\n"); }
int add(int a, int b) {
return a + b;
}
然后输⼊命令
1gcc a.c -fPIC -shared -o a.so
在当前⽬录下会产⽣⼀个a.so⽂件
其中 -fPIC是position independent code(位置⽆关代码)的意思
-shared是产⽣⼀个可以与其他对象连接来形成⼀个可执⾏⽂件的共享对象的⼀个参数⾸先, python中调⽤.so库
1 2 3 4 5 6 7from ctypes import cdll
cur =cdll.LoadLibrary('./a.so') cur.show()
print cur.add(1, 2)
结果如下
1 2hello, world! 3
然后,在C语⾔中调⽤.so⽂件⾸先看⼀组API
1 2 3 4 5#include <dlfcn.h>
void*dlopen(const char*filename, int flag); void*dlsym(void*handle, const char*symbol); int dlclose(void*handle);
char*dlerror(void);
下⾯, 分别解释这⼏个函数
dlopen
dlopen()函数以指定模式打开指定的动态链接库⽂件,并返回动态链接库的句柄。参数flag有以下两种常⽤的值,并且必须指定其⼀。RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执⾏解析,就是不解析这个变量的地址。 RTLD_NOW:与上⾯不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL. dlsym
dlsym()函数根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使⽤这个函数不但可以获取函数地址,也可以获取变量地址。参数的含义如下: handle:由dlopen打开动态链接库后返回的指针; symbol:要求获取的函数或全局变量的名称。
dlclose
dlclose()函数⽤于关闭指定句柄的动态链接库,只有当此动态链接库的使⽤计数为0时,才会真正被系统卸载。
dlerror
当动态链接库操作函数,如dlopen/dlsym/dlclose//执⾏失败时,dlerror()函数可以返回最近的出错信息,返回值为NULL时表⽰操作函数执⾏成功。编程先学c语言还是python
C语⾔⽤户需要包含头⽂件dlfcn.h才能使⽤上述API。
然后, 我们新建⼀个main.c⽂件
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24/**
#include <dlfcn.h>
void *dlopen(const char *filename, int flag); void *dlsym(void *handle, const char *symbol); int dlclose(void *handle);
char *dlerror(void);
**/
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main() {
void*foo = dlopen("./a.so", RTLD_LAZY); dlerror();
void(*fun)() = dlsym(foo, "show");
int(*fun1)(int, int) = dlsym(foo, "add");
fun();
printf("%d\n", fun1(1, 2));
dlclose(foo);
return0;
}
然后编译命令1gcc main.c -ldl 输出结果:
1 2hello, world! 3
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论