您的位置:首页 > 编程语言 > Python开发

Python的学习(十五)---- 调用windows下DLL详解

2012-11-27 23:50 295 查看
Python调用windows下DLL详解

在python中某些时候需要C做效率上的补充,在实际应用中,需要做部分数据的交互。

使用python中的ctypes模块可以很方便调用windows的dll(也包括linux下的so文件),

下面将详细的讲解这个模块,首先介绍一个简单的例子

引入ctypes库  from ctypes import *

假设有一个符合cdecl调用约定的DLL文件,且其中包含一个导出函数Add.

from ctypes import *

dll = CDLL("add.dll")

print dll.Add(1, 102)

结果 103

1. 加载DLL

加载的时候要根据你将要调用的函数是符合什么调用约定的

stdcall调用约定: 两种加载方式

Objdll = ctypes.windll.LoadLibrary("dllpath")

Objdll = ctypes.WinDLL("dllpath")

cdesl调用约定: 两种加载方式

Objdll = ctypes.cdll.LoadLibrary("dllpath")

Objdll = ctypes.CDLL("dllpath")

其实 windll 和 cdll 分别是WinDLL类和CDLL类的对象

2. 调用dll 中的方法

在1中加载dll的时候会返回一个DLL对象,利用该对象就可以调用dll中的方法

3. C基本类型和ctypes中实现的类型映射表

ctypes 数据类型    C 数据类型

c_char                   char

c_short                  short

c_int                      int

c_long                   long

c_ulong                 unsign long

c_float                   float

c_double               double

c_void_p                void

对应的指针类型是在后面加上"_p”, 如int * 是 c_int_p

在python中要实现c语言中的结构,需要用到类

4. DLL中的函数返回一个指针

虽然这不是一个好的编程方法,不过这种情况的处理方法也很简单,其实返回的都是地址,

把他们转换相应的python类型,在通过value属性访问

pchar = dll.getbuffer()

szbuffer = c_char_p(pchar)

print szbuffer.value

5. 处理C中的结构体类型

在python里面申明一个类似C的结构体,要用到类,并且这个类必须继承自Structure,先看个简单的例子

C里面dll的定义如下:

typedef struct _SimpleStruct

{ int nNo;

   float fVirus;

   char szBuffer[512];

}SimpleStruct, *PSimpleStruct;

typedef const SimpleStruct *PCSimpleStruct;

extern "C" int _declspec(dllexport) PrintStruct(PSimpleStruct simp);

int PrintStruct(PSimpleStruct simp)

{  print ("nMaxNume = %f, szConten=%s", simp->fVirus, simp->szBuffer);

    return simp->nNo;

}

Python 的定义:

from ctypes import *

class SimpStruct(Structure):

    _fields_ = [ ("nNo", c_int),

                       ("fVirus", c_float),

                       ("szBuffer", c_char*512)]

dll = CDLL("AddDll.dll")

simple = SimpStruct();

simple.nNo = 16

simple.fVirus = 3.1415926

simple.szBuffer = "magicTong\0"

print dll.PrintStruct(byref(simple))

如果结构体里面有指针,甚至是指向结构体的指针,python里面也有相应的处理方法

C代码如下:

typedef struct

{    char words[10]

} keywords;

typedef struct

{    keywords *kws;

      unsigned int len;

}outStruct;

extern "C" int _declspec(dllexport) test(outStruct *o);

int test(outStruct *o)

{    unsigned int i = 4;

      o-> kws = (keywords *)malloc(sizeof(unsigned char) * 10 * i)

      strcpy(o->kws[0].words, "The First Data");

      strcpy(o->kws[1].words, "The Second Data");

      o->len = i;

      return 1;

}

Python代码如下:

class keywords(Structure):

      _fields_ = [('words', c_char*10)]

class outStruct(Structure):

      _fields_ = [('kws', POINTER(keywords)),

                        ('len', c_int)]

o = outStruct();

dll.test(byref(o));

print o.kws[0].keywords;

print o.kws[1].keywords;

print o.len;

另外,还可以通过调用c++实现的dll来直接调用win32 API,或通过kerel32.dll来启动进程等

摘自  http://wenku.baidu.com/view/954b18333968011ca300917e.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python