python-ctypes模块中文帮助文档

合集下载

python中ctypes的使用尝试

python中ctypes的使用尝试

python中ctypes的使⽤尝试最近在看Python的性能优化⽅⾯的⽂章,突然想起ctypes这个模块,对于这个模块⼀直不是很理解,不过再次看完相关资料有了些新的观点。

ctypes 这个模块个⼈观点就是提供⼀个Python类型与C类型数据转换接⼝或者说是规则的⼀个模块。

ctypes定义的数据类型其实并不是⼀种数据类型,⽽更应该说是⼀种转换规则。

ctypes定义的数据类型都是需要和Python数据类型进⾏关联的,然后传给C函数进⾏调⽤,在C函数调⽤的时候是根据ctypes的数据类型进⾏转换的,把关联的Python数据类型转换为C数据类型传给C函数。

如果是ctypes定义的指针或者地址,其实是将Python变量对应的内存空间地址中的数据与ctypes数据类型进⾏关联,如果C函数内部对传过来的指针地址对应的变量进⾏修改,最后是ctypes将修改好的C数据类型转为Python类型数据并将其存⼊之前Python变量对应的内存空间中。

在调⽤ctypes时,程序的内存空间其实可以分为Python数据内存空间与C数据类型空间。

ctypes定义的数据类型就是提供了⼀个Python数据类型与C数据类型转换的对应关系。

ctypes定义的数据类型都是需要和Python数据类型关联的,在调⽤C函数的时候在实时的转为C数据类型。

其中,Python数据类型存在与Python数据内存空间中,C数据类型存在与C数据内存空间中。

需要注意的⼀点是,⼀般情况下C数据内存空间是实时开辟的,⽤完就及时⾃动销毁的,当然也有特例,那就是numpy定义的array类型变量等, numpy定义的数据类型其实就是⼀种经过包装的C数据类型,当然numpy定义的array等类型变量存在于C数据内存空间中,⽽numpy下的array是可以持续存在的,不会⾃动销毁。

ctypes 提供了⼀些基本数据类型⽤来映射 C 语⾔和 Python 的类型,可以这样说 ctypes 是提供的⼀种数据类型映射关系或是转换关系。

Python调用windows下DLL详解 - ctypes库的使用

Python调用windows下DLL详解 - ctypes库的使用

Python调用windows下DLL详解- ctypes库的使用分类:Python 2008-10-14 19:19 17710人阅读评论(12) 收藏举报pythondllwindowsstructurecclass作者:童磊(magictong)P.S. 之前的排版乱掉了,这里做一下排版,顺便改一下里面的一些用词错误。

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

使用python中的ctypes模块可以很方便的调用windows的dll(也包括linux下的so等文件),下面将详细的讲解这个模块(以windows平台为例子),当然我假设你们已经对windows下怎么写一个DLL是没有问题的。

引入ctypes库[python] view plaincopyprint?from ctypes import *from ctypes import *假设你已经有了一个的DLL(名字是add.dll),且该DLL有一个符合cdecl(这里强调调用约定是因为,stdcall调用约定和cdecl调用约定声明的导出函数,在使用python加载时使用的加载函数是不同的,后面会有说明)调用约定的导出函数Add。

建立一个Python文件DllCall.py测试:[python] view plaincopyprint?from ctypes import *dll = CDLL("add.dll")print dll.Add(1, 102)from ctypes import *dll = CDLL("add.dll")print dll.Add(1, 102)结果:103上面是一个简单的例子。

下面简单聊一下调用流程:1、加载DLL上面已经说过,加载的时候要根据你将要调用的函数是符合什么调用约定的。

stdcall调用约定:两种加载方式[python] view plaincopyprint?Objdll = ctypes.windll.LoadLibrary("dllpath")Objdll = ctypes.WinDLL("dllpath")Objdll = ctypes.windll.LoadLibrary("dllpath")Objdll = ctypes.WinDLL("dllpath")cdecl调用约定:也有两种加载方式[python] view plaincopyprint?Objdll = ctypes.cdll.LoadLibrary("dllpath")Objdll = ctypes.CDLL("dllpath")<SPAN style="FONT-FAMILY: Microsoft YaHei">其实windll和cdll分别是WinDLL类和CDll类的对象。

python ctypes 回调函数

python ctypes 回调函数

python ctypes 回调函数在Python 中,使用ctypes模块可以调用动态链接库(DLL)中的函数,并支持回调函数的使用。

以下是一个简单的示例,演示如何在Python 中使用ctypes调用DLL 中的函数,并注册回调函数。

假设有一个名为example.dll的动态链接库,其中包含一个接受整数参数的函数register_callback,它会注册一个回调函数,并在后续调用时触发该回调函数。

// example.c#include <stdio.h>typedef void (*CallbackFunction)(int);static CallbackFunction callback = NULL;void register_callback(CallbackFunction cb) {callback = cb;}void trigger_callback(int value) {if (callback != NULL) {callback(value);}}编译这个C 文件生成动态链接库:gcc -shared -o example.dll -fPIC example.c然后,你可以使用以下Python 代码调用并测试这个动态链接库:import ctypes# 加载动态链接库example_dll = ctypes.CDLL('./example.dll')# 定义回调函数的类型CallbackFunction = ctypes.CFUNCTYPE(None, ctypes.c_int)# 实现回调函数def my_callback(value):print(f'Callback triggered with value: {value}')# 将回调函数传递给动态链接库中的函数example_dll.register_callback.argtypes = [CallbackFunction] example_dll.register_callback.restype = Noneexample_dll.register_callback(CallbackFunction(my_callback))# 调用触发回调的函数example_dll.trigger_callback(42)在这个例子中,CallbackFunction是一个特殊的函数类型,用于定义回调函数的签名。

Python使用ctypes库调用外部DLL

Python使用ctypes库调用外部DLL

Python:使用ctypes库调用外部DLL一、Python之ctypesctypes是Python的一个外部库,提供和C语言兼容的数据类型,可以很方便地调用C DLL中的函数。

在Python2.5官方安装包都带有ctypes 1.1版。

ctypes的官方文档在这里。

ctypes的使用非常简明,如调用cdecl方式的DLL只需这样:view sourceprint?1 from ctypes import *;2 h=CDLL('msvcrt.dll')3 h.printf('a=%d,b=%d,a+b=%d',1,2,1+2);以上代码运行后输出 a=1,b=2,a+b=3。

二、加载库和普通函数的调用官方API提供的库中有几个主要的函数:view sourceprint?01 //初始化02 int DCSPCLIENTDLL InitInterface( const char *pCenterIP, const unsigned short nUpLinkSvrPort,const unsigned short nDownLinkSvrPort );0304 //释放资源05 int DCSPCLIENTDLL FiniInterface( void );0607 //登录08 int DCSPCLIENTDLL Login( const unsigned int uiBranchPlatformID, const unsigned int nUserID, const char *pPassword );09 //注销10 int DCSPCLIENTDLL Logout( const unsigned int uiBranchPlatformID, const unsigned int nUserID, const char *pPassword );1112 //发车辆实时定位数据13 int DCSPCLIENTDLL SendUPRealLocation( const char * const pDeviceId, const char cDeviceColor,14 const unsigned short nMsgCode, const _stBPDynamicData * const pStGpsData );在Python中加载使用:view sourceprint?01 from ctypes import *0203 #加载API库04 api = CDLL('DCSPClientDLL.dll');05 #初始化函数的参数类型06 api.InitInterface.argtypes=[c_char_p,c_ushort,c_ushort]07 api.Login.argtypes=[c_uint,c_uint,c_char_p]08 api.Logout.argtypes=[c_uint,c_uint,c_char_p]0910 #初始化并登录11 api.InitInterface(u"中心服务器地址" , u'上行服务端端口' , u'下行客户端端口')12 api.Login(platformID,userID,password);13 #.....其它操作14 api.Logout(platformID,userID,password); #注销参数类型可以像上面的代码一样预先设定好,或者在调用函数时再把参数转成相应的c_***类型。

Python使用ctypes模块调用DLL函数之传递结构体参数

Python使用ctypes模块调用DLL函数之传递结构体参数

Python使用ctypes模块调用DLL函数之传递结构体参数引言在Python语言中,可以使用ctypes模块调用其它如C++语言编写的动态链接库DLL文件中的函数,在提高软件运行效率的同时,也可以充分利用目前市面上各种第三方的DLL库函数,以扩充Python软件的功能及应用领域,减少重复编写代码、重复造轮子的工作量,这也充分体现了Python语言作为一种胶水语言所特有的优势。

上篇已经讲了传递数值、指针、字符串参数的例子,详细细节请参考:这次讲一下在Python中使用ctypes模块调用DLL中的库函数传递结构体参数的情况。

同样,操作系统环境是win7 64位,Python使用的版本是python2.7.14,函数约定的调用方式为C调用(cdecl)方式。

例1:简单的结构体传递参数示例这个例子的功能是打印一个学生的信息,并返回一个指向字符串的指针。

其中,学生信息定义为一个结构体类型,包括学生的姓名、年龄及分数信息,该函数的声明及结构体定义如下图所示:函数printStudentInfo的具体C语言实现代码如下:在Python中的调用方式如下:从上面的代码中可以看出,对于结构体参数的传递,在Python中需要使用Structure作为基类定义一个与之对应的结构体类Student,在类的_fields中定义结构体中每个成员变量的名称和数据类型。

然后定义结构体类的一个实例对象student,对每个成员变量逐个赋值,以byref传址的方式进行调用就可以了。

例2:复杂结构体传递参数示例如果一个结构体里面包括了另一个结构体、指针等综合要素,情况就要复杂些了。

对上面的例子改进一下,定义一个People类,里面包含了一个指向Student类型的指针变量和一个整形变量,在这个结构体中存储多个学生的信息及学生的总数信息。

设计一个函数getPeopleInfo获取每个学生的信息,并返回所有学生的个数,该函数的声明及结构体定义如下图所示:函数getPeopleInfo的具体C语言实现代码如下:在Python中的调用方式如下:在上面的代码中,第43行定义了一个指向Student结构体的指针变量。

Python中文手册【Word版 】

Python中文手册【Word版 】
另一种情况:可能你需要使用几个C库来工作,通常C的编写/编译/测试/重编译周期太慢。你需要尽快的开发软件。也许你需要写一个使用扩展语言的程序,但不想设计一个语言,并为此编写调试一个解释器,然后再把它集成进你的程序。
遇到以上情况,Python可能就是你要找的语言。Python很容易上手,但它是一门真正的编程语言,提供了比Shell多的多的结构,支持大型程序。另一方面,它提供了比C更多的错误检查,并且,做为一门高级语言,它拥有内置的高级数据类型,例如可变数组和字典,如果通过C来实现的话,这些工作可能让你大干上几天的时间。因为拥有更多的通用数据类型,Python适合比Awk甚至Perl更广泛的问题领域,在其它的很多领域,Python至少比别的语言要易用得多。
Copyright?1995-2000CorporationforNationalResearchInitiatives.Allrightsreserved.Copyright?1991-1995StichtingMathematischCentrum.Allrightsreserved.
Seetheendofthisdocumentforcompletelicenseandpermissionsinformation.
>>>the_world_is_flat=1
>>>ifthe_world_is_flat:
...print"Becarefulnottofalloff!"
...
Becarefulnottofalloff!解释器打印一个错误信息和栈跟踪(监视)器?。交互模式下,它返回主提示符,如果从文件输入执行,它在打印栈跟踪器后以非零状态退出。(异常可以由try语句中的except子句来控制,这样就不会出现上文中的错误信息)有一些非常致命的错误会导致非零状态下退出,这由通常由内部矛盾和内存溢出造成。所有的错误信息都写入标准错误流;命令中执行的普通输出写入标准输出。

Python中文手册(汉译)Word文字可编辑版

Python中文手册(汉译)Word文字可编辑版

Python 手册Python中文社区Python 手册向上:Python 文档索引向后:前言Python 手册Guido van RossumFred L. Drake, Jr., editorPythonLabsEmail: **********************Release 2.3July 29, 2003前言目录1. 开胃菜2. 使用Python解释器2.1 调用解释器2.1.1 传递参数2.1.2 交互模式2.2 解释器及其工作模式2.2.1 错误处理2.2.2 执行 Python 脚本2.2.3 源程序编码2.2.4 交互环境的启动文件3.初步认识Python3.1 像使用计算器一样使用Python3.1.1 数值3.1.2 字符串3.1.3 Unicode 字符串3.1.4 链表3.2 开始编程4. 流程控制4.1 if 语法4.2 for 语法4.3 range() 函数4.4 break 和continue 语法以及else 子句在循环中的用法4.5 pass 语法4.6 定义函数4.7 定义函数的进一步知识4.7.1 定义参数变量4.7.2 参数关键字4.7.3 可变参数表4.7.4 Lambda 结构4.7.5 文档字符串5. 数据结构5.1 深入链表5.1.1 将链表作为堆栈来使用5.1.2 将链表作为队列来使用5.1.3 函数化的编程工具5.1.4 链表的内含(Comprehensions)5.2 del 语法5.3 Tuples 和 Sequences5.4 字典(Dictionaries)5.5 循环技巧5.6 深入条件控制5.7 Sequences 和其它类型的比较6. 模块6.1 深入模块6.1.1 模块搜索路径6.1.2 “编译” Python 文件6.2 标准模块6.3 dir() 函数6.4 包6.4.1 从包中导入所有内容(import * )6.4.2 隐式包引用6.4.3 包中的多重路径7. 输入和输出7.1 格式化输出7.2 读写文件7.2.1 文件对象的方法7.2.2 pickle 模块8. 错误和异常8.1 语法 Errors8.2 异常8.3 捕获异常8.4 释放异常8.5 用户自定义异常8.6 定义 Clean-up Actions9. 类9.1 一个术语9.2 Python 的生存期和命名空间9.3 类(Classes)的初步印像9.3.1 类定义语法9.3.2 类对象9.3.3 实例对象9.3.4 方法对象9.4 自由标记(Random Remarks)9.5 继承9.5.1 多继承9.6 私有变量9.7 零杂技巧9.8 异常也是类9.9 迭代子(Iterators)9.10 发生器(Generators)10. 接下来?A. 交互式编辑和历史回溯A.1 行编辑A.2 历史回溯A.3 快捷键绑定A.4 注释B. 浮点计算:问题与极限B.1 表达错误C. 历史和授权C.1 本软件的历史C.2 修改和使用Python的条件(Terms and conditions for accessing or otherwise usingPython)关于本文档Python 手册向上:Python 文档索引向后:前言Release 2.3, documentation updated on July 29, 2003.See A bout this document... for information on suggesting changes.Python中文社区前言Python中文社区Python 指南向前:Python 指南向上: P ython 指南向下:目录前言Copyright © 2001, 2002, 2003 Python Software Foundation. All rights reserved.Copyright © 2000 . All rights reserved.Copyright © 1995-2000 Corporation for National Research Initiatives. All rights reserved.Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved.See the end of this document for complete license and permissions information.概要:Python 是一种容易学习的强大语言。

【转】python中使用C类型的数组以及ctypes的用法

【转】python中使用C类型的数组以及ctypes的用法

【转】python中使⽤C类型的数组以及ctypes的⽤法【转⾃】Python 在 ctypes 中为我们提供了类似C语⾔的数据类型,它的⽤途(我理解的)可能是:(1)与其他语⾔(如 C、Delphi 等)写的动态连接库DLL 进⾏交换数据,因为 python 的数据与 DLL难以进⾏数据交换。

(2) python 的字符串⼀旦形成,是不可变的,为了算法的需要,我们有时需要对字符串进⾏原位操作 ( in place ),⽽不想浪费另外的内存空间。

(3) python 具有很简明的语法,⼈们乐于使⽤。

在解决实际问题时,字符串的处理占据了很⼤的开发量。

互联⽹上有很多有⽤的算法可以帮助我们解决问题,如果我们能⽤python 写类似于 C 语⾔的程序,就不需要⽤其他语去写扩展了。

有⼈会问,既然如此,⽤C语⾔,不就好了吗?当然可作这种选择,在⽤ python 的优势在于:既⽤使⽤了C语⾔的优点,也使⽤了Python的最⼤优点:垃圾⾃动回收,代码简洁等。

⼀、导⼊ C 类型库from ctypes import *⼆、常⽤的C 类型(1) c_int 、 c_long 、c_int32C 类型的long int ,这两个类型完全相同。

python ⽤ int 与之相应,但c_int的取值范围是 32 bit 的整数。

占⽤ 4 字节内存(2) c_int6464 bit 整数,占⽤ 8 字节内存, python ⽤ int 与之相应(2) c_double 、c_floatC 类型的 double , 这两个名字( c_double 、c_float 完全相同)占⽤ 8 字节内存python ⽤ float 与之相应(3) c_byteC 类型的 byte , python ⽤ int 与之相应占⽤1字节内存(4) c_charC 的 8 bit 字符型(5) c_wcharC 的 unicode 字符【注】ctypes模块C类型 Python类型 ctypes 类型char 1-character/string c_charwchar_t 1-character/Unicode、string c_wcharchar int/long c_bytechar int/long c_ubyteshort int/long c_shortunsigned short int/long c_ushortint int/long C_intunsigned int int/long c_uintlong int/long c_longunsigned long int/long c_ulonglong long int/long c_longlongunsigned long long int/long c_ulonglongfloat float c_floatdouble float c_doublechar *(NULL terminated) string or none c_char_pwchar_t *(NULL terminated) unicode or none c_wchar_pvoid * int/long or none c_void_p当⼀个函数期望⼀个指针作为参数时,可以像这样调⽤function_main( byref(parameter) ). //struct例⼦下⾯的例⼦是定义⼀个结构C语⾔例⼦struct beer_recipe{int amt_barley;int amt_barley;int amt_water;};Python例⼦class beer_recipe(Structure):_fields_ = [("amt_barley", c_int),("amt_water", c_int),]Union结构例⼦C语⾔例⼦union {long barley_long;int barley_int;char barley_char[8];}barley_amount;Python例⼦class barley_amount(Union):_fields_ = [("barley_long", c_long),("barley_int", c_int),("barley_char", c_char * 8),]三、⽣成类似C的数组⽬的:初值化⼀个具有 10 个元素的数组,每个元素初值为0的(⼀) python 原⽣数组 list>>> a = [ 0 ] * 10>>> for i in range(0, len(a)): print( a[i], end=" ")0 0 0 0 0 0 0 0 0 0 >>>(⼆)⽣成 10 元素的 c_int 类型的数组:格式⼀:>>> from ctypes import *>>> a = ( c_int * 10) ()>>> for i in range(0, len(a)):print( a[i], end=" ")0 0 0 0 0 0 0 0 0 0>>>格式⼆:>>> from ctypes import *>>> M = 10>>> a = ( c_int * M ) ()>>> for i in range(0, len(a)):print( a[i], end=" ")0 0 0 0 0 0 0 0 0 0格式三:>>> from ctypes import *>>> myArr10 = c_int * 10>>> a = myArr10( )>>> for i in range(0, len(a)):print( a[i], end=" ")0 0 0 0 0 0 0 0 0 0c_double 的数组定义与上⾯相似。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

内容:.加载动态链接库.从已加载的dll中引用函数.调用函数1.基本的数据类型.调用函数2.用自己的数据类型调用函数.确认需要的参数类型(函数原型).返回值.传递指针.结构和联合.结构或联合的对齐方式和字节的顺序.结构和联合中的位.数组.指针.类型转换.未完成的类型.回调函数.访问dlls导出的值.可变长度的数据类型.bugs 将要做的和没有做的事情注意:本文中的代码例子使用doctest确保他们能够实际工作。

一些代码例子在linux和windows以及苹果机上执行有一定的差别注意:一些代码引用了ctypes的c_int类型。

它是c_long在32位机子上的别名,你不应该变得迷惑,如果你期望的是c_int类型,实事上打印的是c_long,它们实事上是相同的类型。

加载动态链接库ctypes加载动态链接库,导出cdll和在windows上同样也导出windll和oledll对象。

加载动态链接库后,你可以像使用对象的属性一样使用它们。

cdll加载使用标准的cdecl调用约定的链接库,而windll库使用stdcall调用约定,oledll也使用stdcall调用约定,同时确保函数返回一个windows HRESULT错误代码。

这错误代码自动的升为WindowsError Python exceptions,当这些函数调用失败时。

这有一些windows例子,msvcrt是微软的c标准库,包含大部分的标准c函数,同时使用cdecl调用约定。

注:cdecl和stdcall的区别请见/log-20.html>>> from ctypes import *>>> print windll.kernel32 # doctest: +WINDOWS<WinDLL 'kernel32', handle ... at ...>>>> print cdll.msvcrt # doctest: +WINDOWS<CDLL 'msvcrt', handle ... at ...>>>> libc = cdll.msvcrt # doctest: +WINDOWS>>>windows自动添加常用的.dll文件后缀名在linux上,需要使用包含扩展名的文件名来加载一个库,因此属性操作不能正常使用。

或者使用dll加载器的LoadLibrary方法,或者通过CDLL构造函数创建一个CDLL的一个实例>>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX<CDLL 'libc.so.6', handle ... at ...>>>> libc = CDLL("libc.so.6") # doctest: +LINUX>>> libc # doctest: +LINUX<CDLL 'libc.so.6', handle ... at ...>>>>加载dll使用其中函数使用函数就像对象的属性>>> from ctypes import *>>> libc.printf<_FuncPtr object at 0x...>>>> print windll.kernel32.GetModuleHandleA # doctest: +WINDOWS<_FuncPtr object at 0x...>>>> print windll.kernel32.MyOwnFunction # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?File "ctypes.py", line 239, in __getattr__func = _StdcallFuncPtr(name, self)AttributeError: function 'MyOwnFunction' not found>>>00注意win32系统dll像kernel32和user32大部分导出ANSI和UNICODE版本函数,UNICODE 版本以一个W结尾导出而ANSI版本则以一个A结尾导出的。

win32 GetModuleHandle函数,返回一个指定的module 名字的module句柄下面c原型,GetModuleHandle的macro,依赖于它是不是UNICODE。

/* ANSI version */HMODULE GetModuleHandleA(LPCSTR lpModuleName);/* UNICODE version */HMODULE GetModuleHandleW(LPCWSTR lpModuleName);windll不会神奇的自已去选择一个,你必须显式确认GetModuleHandleA或者GetModuleHandleW去使用它们去处理一般字符串或unicode字符串。

有时候,dll导出函数名,python无法识别,像"??2@YAPAXI@Z". 在这情况下,你必须使用getattr去使用这些函数>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") # doctest: +WINDOWS<_FuncPtr object at 0x...>>>>在windows上,一些dllS不是导出函数名,而是以顺序,这些函数可以将这些数字当作dll 对象的索引来使用这些函数。

>>> cdll.kernel32[1] # doctest: +WINDOWS<_FuncPtr object at 0x...>>>> cdll.kernel32[0] # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?File "ctypes.py", line 310, in __getitem__func = _StdcallFuncPtr(name, self)AttributeError: function ordinal 0 not found>>>调用函数你可调用这些函数,像其它的python函数一样,下面的例子使用time()函数,它以秒为单位返回从unix新纪元的系统时间,GetModuleHandleA()函数,返回一个win32模块句柄。

下面的例子用空指针调用函数(None作为空指针)>>> print libc.time(None) # doctest: +SKIP1150640792>>> print hex(windll.kernel32.GetModuleHandleA(None)) # doctest: +WINDOWS0x1d000000>>>ctypes尝试阻止你以错误的参数数量或调用约定来调用函数。

不幸的是,这些仅仅能在windows上工作它在函数返回后不会去检查这栈,尽管在调用函数后有错误发生。

>>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?ValueError: Procedure probably called with not enough arguments (4 bytes missing)>>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?ValueError: Procedure probably called with too many arguments (4 bytes in excess)>>>产生了同样的exception,当你用cdecl调用约定去使用一个stdcall函数,反之亦然。

>>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?ValueError: Procedure probably called with not enough arguments (4 bytes missing)>>>>>> windll.msvcrt.printf("spam") # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?ValueError: Procedure probably called with too many arguments (4 bytes in excess)>>>找到正确的调用约定,你必须检查c头文件或者你想调用的函数的文档。

在windows,ctypes使用win32结构exception处理一般的保护错误阻止crashes,当调用无效的参数值>>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWSTraceback (most recent call last):File "<stdin>", line 1, in ?WindowsError: exception: access violation reading 0x00000020>>>然而有很多种可能性会发生crash,你使用python的ctypes,你应该足够的小心。

相关文档
最新文档