引用so动态链接库的方法
from ctypes import cdll
lib = cdll.LoadLibrary('/home/zhengli/test/test.so')
lib.func()
总结:
1、引用ctypes库中的cdll类。
2、利用cdll的LoadLibrary方法加载so包,生成对象。
3、利用对象执行so包的可执行方法。
注意:
1、最好以绝对路径加载so包,相对路径不好控制。
2、编写so包时候,要将发布的功能用 extern "C" {} 框起来。
3、编译参数:
(1) 在编译.o文件时:g++ -c -fPIC *.cpp -o *.o。注意“-fPIC”参数一定要有;
(2) 在编译.so文件时:g++ -shared -Wl -o *.o *
4、如果python在调用C函数内部出现了问题,系统不会提示具体出现什么问题,只会提示"segmentation fault"。所以最好是先用C语言调用该动态库验证没有问题了再提供给python调用。
5、python传参给C函数时,可能会因为python传入实参与C函数形参类型不一致会出现问题( 一般int, string不会有问题,float要注意 )。这时需要在python调用时传入的实参做一个类型转换(见so.add(float, float)函数的调用)。转换方式见下表:
6、如果将python中list传入C函数数组,则需要提前转换。
import ctypes pyarray = [ 1 , 2 , 3 , 4 , 5 ] carrary = (ctypes.c_int * len (pyarray))( * pyarray) / / 有点类似malloc的方式生成carray print so.sum_array(carray, len (pyarray)) |
7、如何调用C++中的类
因为python不能直接调用C++中的类,所以必须把C++中的类转换为C的接口
转换原则
- 所有的C++关键字及其特有的使用方式均不能出现在.h文件里,.h中仅有C函数的包装函数声明
- 在class.cpp中实现对类的成员函数接口转换的函数,包括对类内成员的读写函数get() and set()
- 如果要在包装函数中要实例化对象,尽量用new constructor()的将对象的内存实例化在堆中,否则对象会被析构
-
记得在所有包含函数声明的文件中加入以下关键字,声明该函数为C函数,否则该函数的符号不会记录在二进制文件中
#ifdef __cplusplus extern "C" { #endif xxxxxx function declaration xxxxx #ifdef __cplusplus } #endif |