博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10 python 扩展
阅读量:4701 次
发布时间:2019-06-09

本文共 2899 字,大约阅读时间需要 9 分钟。

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

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

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

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

正文开始:

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

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

接下来举个简单例子

1 //hello.h 2 #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_DLL14 #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.h 2 #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 2010  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_DLL28 #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 typeINTARRAY20 = c_int * ARRAY_NUMBER;CHARARRAY20 = c_char * STR_LEN;#define structclass StructTest(Structure):  _fields_ = [    ("number", c_int),    ("pChar", c_char_p),    ("str", CHARARRAY20),    ("iArray", INTARRAY20)        ]#load dll and get the function objectdll = cdll.LoadLibrary('hello.dll');GetStructInfo = dll.GetStructInfo;#set the return typeGetStructInfo.restype = c_char_p;#set the argtypesGetStructInfo.argtypes = [POINTER(StructTest)];objectStruct = StructTest();#invoke api GetStructInforetStr = GetStructInfo(byref(objectStruct));#check resultprint "number: ", objectStruct.number;print "pChar: ", objectStruct.pChar;print "str: ", objectStruct.str;for i,val in enumerate(objectStruct.iArray):  print 'Array[i]: ', val;print retStr;

 

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

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

转载于:https://www.cnblogs.com/lixiaofou/p/7820380.html

你可能感兴趣的文章
codevs1018 单词接龙(DFS)
查看>>
内容分发系统MediaEW:助新闻媒体转投HTML5
查看>>
HTML5 Canvas ( 径向渐变, 升级版的星空 ) fillStyle, createRadialGradient
查看>>
Stanford Local Programming Contest 2011
查看>>
Sql server锁,独占锁,共享锁,更新锁,乐观锁,悲观锁
查看>>
关于javascript dom扩展:Selector API
查看>>
多线程中,NSOperationQueue和GCD的区别
查看>>
python生成.exe文件
查看>>
STM32,你了解多少?(转载)
查看>>
用anaconda保证64位和32位的python共存
查看>>
cPanel设置自定义404错误页
查看>>
16.垃圾最小化
查看>>
ROS time stamp and sync
查看>>
将 Shiro 作为应用的权限基础 三:基于注解实现的授权认证过程
查看>>
遍历聚合对象中的元素——迭代器模式(四)
查看>>
Ehab and subtraction(思维题)
查看>>
Codeforces Round 56-C. Mishka and the Last Exam(思维+贪心)
查看>>
统计汉字
查看>>
使用JavaScript重定向URL参数
查看>>
Tomcat系列(5)——Tomcat配置详细部分
查看>>