http://blog.csdn.net/magictong/archive/2008/10/14/3075478.aspx
貌似原文的网页服务器有问题,总是
load
不全,所以备个份:
Python
调用
windows
下
DLL
详解
在
python
中某些时候需要
C
做效率上的补充,在实际应用中,需要做部分数据的交互。使用
python
中的
ctypes
模块可以很方便的调用
windows
的
dll
(也包括
linux
下的
so
等文件),
下面将详细的讲解这个模块(以
windows
平台为例子),当然我假设你们已经对
windows
下怎
么写一个
DLL
是没有问题的。
引入
ctypes
库
from ctypes import *
假设你有了一个符合
cdecl
(这里强调调用约定是因为,
stdcall
调用约定和
cdecl
调用约定声
明的导出函数,在用
python
加载使用的加载函数是不同的,后面会说明)调用约定的
DLL
(名
字是
add.dll)
,且有一个导出函数
Add
。
建立一个
Python
文件
DllCall.py
测试:
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")
cdecl
调用约定:也有两种加载方式
Objdll = ctypes.cdll.LoadLibrary("dllpath")
Objdll = ctypes.CDLL("dllpath")
其实
windll
和
cdll
分别是
WinDLL
类和
CDll
类的对象。
2
、调用
dll
中的方法
在
1
中加载
dll
的时候会返回一个
DLL
对象
(假设名字叫
Objdll
)
,
利用该对象就可以调用
dll
中的方法。
e.g.
如果
dll
中有个方法名字叫
Add
(注意如果经过
stdcall
声明的方法,
如果不是用
def
文件
声明的导出函数的话,编译器会对函数名进行修改,这个要注意)
调用:
nRet = Objdll.Add(12, 15)
即完成一次调用。
看起来调用似乎很简单,不要只看表象,呵呵,这是因为
Add
这个函数太简单了,现在假设函
数需要你传入一个
int
类型的指针(
int*
),可以通过库中的
byref
关键字来实现,假设现在
调用的函数的第三个参数是个
int
类型的指针。
intPara = c_int(9)
dll.sub(23, 102, byref(intPara))
print intPara.value
如果是要传入一个
char
缓冲区指针,和缓冲区长度,方法至少有四种:
# char* -- 1
szPara = create_string_buffer('\0'*100)
dll.PrintInfo(byref(szPara), 100);
print szPara.value
# char* -- 2