Python调用windows下DLL详解ctypes库的使用Word文件下载.docx
- 文档编号:19545952
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:18
- 大小:20.01KB
Python调用windows下DLL详解ctypes库的使用Word文件下载.docx
《Python调用windows下DLL详解ctypes库的使用Word文件下载.docx》由会员分享,可在线阅读,更多相关《Python调用windows下DLL详解ctypes库的使用Word文件下载.docx(18页珍藏版)》请在冰豆网上搜索。
ctypes.windll.LoadLibrary("
dllpath"
ctypes.WinDLL("
Objdll=ctypes.windll.LoadLibrary("
Objdll=ctypes.WinDLL("
cdecl调用约定:
也有两种加载方式
ctypes.cdll.LoadLibrary("
ctypes.CDLL("
<
SPAN
style="
FONT-FAMILY:
Microsoft
YaHei"
>
其实windll和cdll分别是WinDLL类和CDll类的对象。
/SPAN>
Objdll=ctypes.cdll.LoadLibrary("
Objdll=ctypes.CDLL("
2、调用dll中的方法
在1中加载dll的时候会返回一个DLL对象(假设名字叫Objdll),利用该对象就可以调用dll中的方法。
e.g.如果dll中有个方法名字叫Add(注意如果经过stdcall声明的方法,如果不是用def文件声明的导出函数或者extern“C”声明的话,编译器会对函数名进行修改,这个要注意,我想你们懂的。
调用:
nRet=Objdll.Add(12,15)即完成一次调用。
看起来调用似乎很简单,不要只看表象,呵呵,这是因为Add这个函数太简单了,现在假设函数需要你传入一个int类型的指针(int*),可以通过库中的byref关键字来实现,假设现在调用的函数的第三个参数是个int类型的指针。
intPara
c_int(9)
dll.sub(23,
102,
byref(intPara))
intPara.value
intPara=c_int(9)
dll.sub(23,102,byref(intPara))
printintPara.value
如果是要传入一个char缓冲区指针,和缓冲区长度,方法至少有四种:
#
方法1
szPara
create_string_buffer('
/0'
*100)
dll.PrintInfo(byref(szPara),
100);
szPara.value
方法2
sBuf
'
aaaaaaaaaabbbbbbbbbbbbbb'
pStr
c_char_p(
pStr.value
#pVoid
ctypes.cast(
pStr,
ctypes.c_void_p
).value
dll.PrintInfo(pStr,
len(pStr.value))
方法3
strMa
"
/0"
*20
FunPrint
dll.PrintInfo
FunPrint.argtypes
[c_char_p,
c_int]
#FunPrint.restypes
c_void_p
nRst
FunPrint(strMa,
len(strMa))
strMa,len(strMa)
方法4
pStr2
c_char_p("
pStr2.value
dll.PrintInfo(pStr2,
#方法1
szPara=create_string_buffer('
*100)
dll.PrintInfo(byref(szPara),100);
printszPara.value
#方法2
sBuf='
pStr=c_char_p()
pStr.value=sBuf
#pVoid=ctypes.cast(pStr,ctypes.c_void_p).value
dll.PrintInfo(pStr,len(pStr.value))
printpStr.value
#方法3
strMa="
*20
FunPrint=dll.PrintInfo
FunPrint.argtypes=[c_char_p,c_int]
#FunPrint.restypes=c_void_p
nRst=FunPrint(strMa,len(strMa))
printstrMa,len(strMa)
#方法4
pStr2=c_char_p("
printpStr2.value
dll.PrintInfo(pStr2,len(pStr.value))
3、C基本类型和ctypes中实现的类型映射表
ctypes数据类型
C数据类型
c_char
char
c_short
short
c_int
int
c_long
long
c_ulong
unsignlong
c_float
float
c_double
double
void
对应的指针类型是在后面加上"
_p"
,如int*是c_int_p等等。
在python中要实现c语言中的结构,需要用到类。
4、DLL中的函数返回一个指针。
虽然这不是个好的编程方法,不过这种情况的处理方法也很简单,其实返回的都是地址,把他们转换相应的python类型,再通过value属性访问。
pchar
dll.getbuffer()
szbuffer
c_char_p(pchar)
szbuffer.value
pchar=dll.getbuffer()
szbuffer=c_char_p(pchar)
printszbuffer.value
5、处理C中的结构体类型
为什么把这个单独提出来说呢,因为这个是最麻烦也是最复杂的,在python里面申明一个类似c的结构体,要用到类,并且这个类必须继承自Structure。
先看一个简单的例子:
C里面dll的定义如下:
[cpp]viewplaincopyprint?
typedef
struct
_SimpleStruct
{
int
nNo;
float
fVirus;
char
szBuffer[512];
}
SimpleStruct,
*PSimpleStruct;
const
SimpleStruct*
PCSimpleStruct;
extern
C"
__declspec(dllexport)
PrintStruct(PSimpleStruct
simp);
simp)
printf
("
nMaxNum=%f,
szContent=%s"
simp->
fVirus,
szBuffer);
return
typedefstruct_SimpleStruct
{
intnNo;
floatfVirus;
charszBuffer[512];
}SimpleStruct,*PSimpleStruct;
typedefconstSimpleStruct*PCSimpleStruct;
extern"
int__declspec(dllexport)PrintStruct(PSimpleStructsimp);
intPrintStruct(PSimpleStructsimp)
printf("
nMaxNum=%f,szContent=%s"
simp->
fVirus,simp->
returnsimp->
}
Python的定义:
class
SimpStruct(Structure):
_fields_
[
nNo"
c_int),
fVirus"
c_float),
szBuffer"
512)]
AddDll.dll"
simple
SimpStruct();
simple.nNo
16
simple.fVirus
3.1415926
simple.szBuffer
magicTong/0"
dll.PrintStruct(byref(simple))
classSimpStruct(Structure):
_fields_=[("
c_int),
("
c_float),
c_char*512)]
simple=SimpStruct();
simple.nNo=16
simple.fVirus=3.1415926
simple.szBuffer="
printdll.PrintStruct(byref(simple))
上面例子结构体很简单,但是如果结构体里面有指针,甚至是指向结构体的指针,处理起来会复杂很多,不过Python里面也有相应的处理方法,下面这个例子来自网上,本来想自己写个,懒得写了,能说明问题就行:
C代码如下:
words[10];
}keywords;
keywords
*kws;
unsigned
len;
}outStruct;
test(outStruct
*o);
*o)
i
4;
o->
kws
(keywords
*)malloc(sizeof(unsigned
char)
10
i);
strcpy(o->
kws[0].words,
The
First
Data"
);
kws[1].words,
Second
len
i;
1;
typedefstruct
charwords[10];
keywords*kws;
unsignedintlen;
int__declspec(dllexport)test(outStruct*o);
inttest(outStruct*o)
unsignedinti=4;
kws=(keywords*)malloc(sizeof(unsignedchar)*10*i);
kws[0].words,"
TheFirstData"
kws[1].words,"
TheSecondData"
len=i;
return1;
Python代码如下:
keywords(Structure):
[('
words'
*10),]
outStruct(Structure):
kws'
POINTER(keywords)),
('
len'
c_int),]
o
outStruct()
dll.test(byref(o))
o.kws[0].words;
o.kws[1].words;
o.len
classkeywords(Structure):
_fields_=[('
c_char*10),]
classoutStruct(Structure):
POINTER(keywords)),
('
c_int),]
o=outStruct()
dll.test(byref(o))
printo.kws[0].words;
printo.kws[1].words;
printo.len
6、例子
说得天花乱坠,嘿嘿,还是看两个实际的例子。
例子1:
这是一个GUID生成器,其实很多第三方的python库已经有封装好的库可以调用,不过这得装了那个库才行,如果想直接调用一些API,对于python来说,也要借助一个第三方库才行,这个例子比较简单,就是用C++调用win32API来产生GUID,然后python通过调用C++写的dll来获得这个GUID。
C++代码如下:
char*
newGUID();
newGUID()
static
buf[64]
{0};
statc
GUID
guid;
if
(S_OK
==
:
CoCreateGuid(&
guid))
_snprintf(buf,
sizeof(buf),
%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
guid.Data1,
guid.Data2,
guid.Data3,
guid.Data4[0],
guid.Data4[1],
guid.Data4[2],
guid.Data4[3],
guid.Data4[4],
guid.Data4[5],
guid.Data4[6],
guid.Data4[7]
MessageBox(NULL,
buf,
GUID"
MB_OK);
(char*)buf;
__declspec(dllexport)char*newGUID();
char*newGUID()
staticcharbuf[64]={0};
statcGUIDguid;
if(S_OK==:
guid))
{
_snprintf(buf,sizeof(buf),
guid.Data1,
guid.Data2,
guid.Data3,
guid.Data4[0],guid.Data4[1],
guid.Data4[2],guid.Data4[3],
guid.Data4[4],guid.Data4[5],
guid.Data4[6],guid.Data4[7]
:
MessageBox(NULL,buf,"
MB_OK);
}
return(char*)buf;
def
CreateGUID():
创建一个全局唯一标识符
类似:
E06093E2-699A-4BF2-A325-4F1EADB50E18
NewVersion
try:
path
strDllPath
sys.path[0]
+
str(os.sep)
createguid.dll"
CDLL(strDllPath)
b
dll.newGUID()
a
c_char_p(b)
except
Exception,
error:
error
a.value
defCreateGUID():
"
创建一个全局唯一标识符
类似:
E06093E2-699A-4BF2-A325-4F1EADB50E18
NewVersion
try:
#dllpath
strDllPath=sys.path[0]+str(os.sep)+"
dll=CDLL(strDllPath)
b=dll.newGUID()
a=c_char_p(b)
exceptException,error:
printerror
return"
returna.value
例子2:
这个例子是调用kernel32.dll中的createprocessA函数来启动一个记事本进程
-*-
coding:
utf-8
定义_PROCESS_INFORMATION结构体
_PROCESS_INFORMATION(Structure):
hProcess'
c_void_p),
hThread'
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Python调用windows下DLL详解 ctypes库的使用 Python 调用 windows DLL 详解 ctypes 使用
![提示](https://static.bdocx.com/images/bang_tan.gif)