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)函数的调用)。转换方式见下表:
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
|