10 python 扩展

说起来扩展,基本就是在其他语言里调用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.cpp
13 #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.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 20
10
11 struct StructTest
12 {
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.cpp
26 #include <string.h>
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
class StructTest(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 in enumerate(objectStruct.iArray):
  print ‘Array[i]: ‘, val;
print retStr;

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

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

时间: 2024-10-13 08:32:51

10 python 扩展的相关文章

python扩展实现方法--python与c混和编程

Reference: http://www.cnblogs.com/btchenguang/archive/2012/09/04/2670849.html python 头文件在的位置:/usr/include/python2.7                                  /usr/local/include/python2.7 前言(更新:更方便易用的方式在http://www.swig.org/tutorial.html) 大部分的Python的扩展都是用C语言写的,

监控开发之用python扩展dstat插件自定义实时监控

dstat是一个python开源的实时监控工具,一般是用来做系统性能监控的.咱们这里只是提他的自定义插件开发,用来打造自己的dstat. 有朋友可能还没清楚是啥意思, 咱们查看系统的状体状态有人喜欢用vmstat,也有人喜欢用dstat.相比来说dstat的功能模块更全一点是,这里还只是说查看系统性能方面的 !   如果想一边查看,系统的各方面性能指标,还想看你应用的一些个负载相关,比如某个程序的负载,mongodb的锁lock百分比,mysql连接数...   懂了吧 ! 下面是dstat的插

python扩展实现方法--python与c混和编程 转自:http://www.cnblogs.com/btchenguang/archive/2012/09/04/2670849.html

前言 需要扩展Python语言的理由: 创建Python扩展的步骤 1. 创建应用程序代码 2. 利用样板来包装代码 a. 包含python的头文件 b. 为每个模块的每一个函数增加一个型如PyObject* Module_func()的包装函数 c. 为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组 d. 增加模块初始化函数void initMethod() 3. 编译与测试 a. 创建setup.py b. 通过运行setup.py来编译和连接你的代码 c.

Python 扩展技术总结(转)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 38.0px; font: 24.0px "PingFang SC Semibold"; color: #2c3033 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 38.0px; font: 14.0px Times; color: #bbbbbb } p.p4 { margin: 0.0px 0.0px 16.0p

Python扩展包

Python扩展包 1.NumPy NumPy提供了多种python本身不支持的多种集合,有list.ndarray和ufunc. list 更加灵活的数组,支持多维,数据可不同型,存储数量远大于array.array只支持同型数据,空间有限. ndarray 多维数组类,方便操纵多维数组,数据必须同型,操纵高效. ufunc 对数组进行高效处理的函数.主要用于高维数组的访问,底层使用c/c++实现. 1.1 构造数组 import numpy as np # 一维数组 arr = np.arr

vs2013在图像处理中的应用(7):开发Python扩展

快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 很久没有摸图像处理的东西了,近期刚好需要有此需求,希望能够有一个比较好用的开发环境.在学校的时候做图像处理一直用的是matlab,不过现在正好在做VELT的开发,尝试用vs2013+python构造一个适合于自己用的开发环境. 在图像处理中,虽然已经可以用python操纵opencv完成一些算法,但总免不了需要自己写一

window下python 扩展库安装 使用第三方镜像源

0.前言 由于python的官方镜像位于国外,若使用pip或者easy_install安装第三方插件时或许会被限制,甚至连easy_install或pip也无法安装,例如在windows环境下运行ez_setup.py 安装easy_install,可能遇到下图这样尴尬的情况. 图1 运行ez_setup.py失败 遇到这种问题可以”转战“国内的第三方镜像,问题便可迎刃而解.例如豆瓣镜像——http://pypi.douban.com/simple/ 1.安装easy_install 先安装ea

python基础:python扩展包的安装方式

python扩展包有三种安装方式: 1. pip安装方式.python3默认自带pip,无需另外安装:在python2.7版本上默认为easy_install安装工作进行安装,如果需要使用pip安装,需要自行下载安装(可以从http://www.pip-installer.org网站下载). 2. 系统自带的包安装管理工具. 3. 从源代码安装. 使用pip安装:在command命令行中输入:pip install 包名,例如:pip install flask 使用pip安装指定版本:在com

【Android】10.1 扩展组件库和其他视图--本章示例主界面

分类:C#.Android.VS2015: 创建日期:2016-02-18 1.主界面运行截图 2.MainActivity.cs文件中对应的代码 chItems.Add(new Chapter() { ChapterName = "第10章 扩展组件库和其他视图", ChapterItems = new ChItem[] { new ChItem { type=typeof(ch1001Main), Title="例10-1 网格视图基本用法", Desc = &