python 扩展_10 python 扩展

说起来扩展,基本就是在其他语言里调用C或者C++,因为这两个是效率最高的代码,而其他大多都是另外又封装的,所以效率较低。

当出现语言本身无法解决的效率问题时,就需要扩展调用其他代码。

因为我自己会C++,所以我就只记录调用C++。

其中调用DLL最为简单,所以在此自己mark一下。

正文开始:

C++中生成DLL就不废话了。需要特别注意的是据我所知VS2010之前的版本貌似只能编译成32位的DLL,但是我的电脑安装的是64位的python,调用32位的就会出错。

解决办法就是用VS2010,在2010中可以编译成64位的DLL。具体方法是在上边的win32中选择编辑新的方式,里边可以选。

接下来举个简单例子

1 //hello.h2 #ifdef EXPORT_HELLO_DLL

3 #define HELLO_API __declspec(dllexport)

4 #else

5 #define HELLO_API __declspec(dllimport)

6 #endif

7 extern "C"

8 {9 HELLO_API int IntAdd(int , int);10 }11

12 //hello.cpp13 #define EXPORT_HELLO_DLL

14 #include "hello.h"

15 HELLO_API int IntAdd(int a, int b)16 {17 return a +b;18 }

上述是两个文件,也就是C++中需要编译DLL的文件。

1 from ctypes import *

2 dll = cdll.LoadLibrary('hello.dll')3 ret = dll.IntAdd(2, 4)4 print(ret)

上述是调用DLL文件的代码,其实就是用到了ctypes库。

以上是一个"hello world"级别的程序,实际运用中更多的需要传递数据结构、字符串等,才能满足我们的需求。那么本示例将展示,如何传递数据结构参数,以及如何通过数据结构获取返回值。

1 //hello.h2 #ifdef EXPORT_HELLO_DLL

3 #define HELLO_API __declspec(dllexport)

4 #else

5 #define HELLO_API __declspec(dllimport)

6 #endif

7

8 #define ARRAY_NUMBER 20

9 #define STR_LEN 20

10

11 struct StructTest12 {13 int number;14 char*pChar;15 char str[STR_LEN];16 int iArray[ARRAY_NUMBER];17 };18

19 extern "C"

20 {21 //HELLO_API int IntAdd(int , int);22 HELLO_API char* GetStructInfo(struct StructTest*pStruct);23 }24

25 //hello.cpp26 #include

27 #define EXPORT_HELLO_DLL

28 #include "hello.h"

29

30 HELLO_API char* GetStructInfo(struct StructTest*pStruct)31 {32 for (int i = 0; i < ARRAY_NUMBER; i++)33 pStruct->iArray[i] =i;34 pStruct->pChar = "hello python!";35 strcpy (pStruct->str, "hello world!");36 pStruct->number = 100;37 return "just OK";38 }

GetStructInfo这个函数通过传递一个StructTest类型的指针,然后对对象中的属性进行赋值,最后返回"just OK".

编写Python调用代码如下,首先在Python中继承Structure构造一个和C DLL中一致的数据结构StructTest,然后设置函数GetStructInfo的参数类型和返回值类型,最后创建一个StructTest对象,并将其转化为指针作为参数,调用函数GetStrcutInfo,最后通过输出数据结构的值来检查是否调用成功:

from ctypes import *ARRAY_NUMBER= 20;

STR_LEN= 20;#define type

INTARRAY20 = c_int *ARRAY_NUMBER;

CHARARRAY20= c_char *STR_LEN;#define struct

classStructTest(Structure):

_fields_=[

("number", c_int),

("pChar", c_char_p),

("str", CHARARRAY20),

("iArray", INTARRAY20)

]#load dll and get the function object

dll = cdll.LoadLibrary('hello.dll');

GetStructInfo=dll.GetStructInfo;#set the return type

GetStructInfo.restype =c_char_p;#set the argtypes

GetStructInfo.argtypes =[POINTER(StructTest)];

objectStruct=StructTest();#invoke api GetStructInfo

retStr =GetStructInfo(byref(objectStruct));#check result

print "number:", objectStruct.number;print "pChar:", objectStruct.pChar;print "str:", objectStruct.str;for i,val inenumerate(objectStruct.iArray):print 'Array[i]:', val;print retStr;

最后要说一点,这些内容不是原创,只是我用别人的方法,自己验证时候遇到的问题,比如64位DLL的问题。

http://blog.csdn.net/bluehawksky/article/details/39082125 更详细的各种数据结构的传递可以看这个。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值