相当于翻译了这篇文章,How to write a DLL/SO in C/C++ for Python,我的目的是为了备注一下我使用失败的情况。
首先,作者推荐了Cython可以作为一个更好的C的python封装,我没去用,直接用vs的工具来生成如下dll吧
C程序 //test.c __declspec(dllexport) int sum(int a, int b) { return a + b; } C++ //test.cpp #define DLLEXPORT extern "C" __declspec(dllexport) DLLEXPORT int sum(int a, int b) { return a + b; }
//test.h int sum(int, int);
从python2.5起已经默认包含了ctypes,否则请自行安装(easyinstall或pip,或下载)
>>> from ctypes import cdll
>>> mydll = cdll.LoadLibrary('test.dll')
>>> mydll
<CDLL 'test.dll', handle 10000000 at b92310>
windows在当前目录自动搜索,Linux请传入路径:
>>> from ctypes import cdll
>>> mydll = cdll.LoadLibrary('/home/wolf/test.so')
>>> mydll
<CDLL '/home/wolf/test.so', handle 9ba7d30 at b7e55d2c>
测试:
>>> mydll.sum
<_FuncPtr object at 0x00AF6918>
>>> mydll.sum(5, 3)
>>> 8
==好了,以上是原文,我的问题如下:
1, 因为开发环境是x64,也就装了64位版的python,结果老是失败,装回32位版的,以上测试直接通过,绝对是64位的原因,哪怕这个dll是在我的64位机器上编译的。几台装了x64的python都没有调成功
2, 下面是这样的一个C方法,需要传入一个int数组和一个字符数组int CCaptionApp(int times,int length, int *ids,char *message) { int n,m=0; for(n=0;n<length;n++) { m+=ids[n]; } return m; }
经实测,字符数组直接传string即可,int数组我也想如法炮制:
>>> from ctypes import cdll
>>> mydll = CDLL('test.dll') #顺便演示另一种加载方式,书写快一些
>>> mydll.CCaptionApp(1,3,[3,4,5],'hello')
输出:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 3: <type 'exceptions.TypeError'>: Don't know how to convert parameter 3
看样子这个巧是不能取的(BTW,.net直接用int[]调即可), 查了下文档,其中的15.17.1.13 Array一节:
>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> print ii
<c_long_Array_10 object at 0x...>
>>> for i in ii: print i,
...
1 2 3 4 5 6 7 8 9 10
>>>
那就是要我们用长度构造一个数组,OK,测试:
>>> from ctypes import *
>>> mydll = CDLL('test.dll')
>>> mydll.CCaptionApp(1,3,(c_Int*3)(3,4,5),'hello')
>>> 12
成功