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之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模块调用其它如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-ctypes模块中文帮助文档

内容:.加载动态链接库.从已加载的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上,需要使用包含扩展名的文件名来加载一个库,因此属性操作不能正常使用。
Python中文手册【Word版 】

遇到以上情况,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 手册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 在 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 的数组定义与上⾯相似。
使用python的内置ctypes模块与c、c++写的dll进行交互

使用python的内置ctypes模块与c、c++写的dll进行交互from ctypes import *dll = CDLL("add.dll")#加载cdecl的dll。
另外加载stdcall的dll 的方式是WinDLL("dllpath")sum=dll.Add(1, 102)p=1sum=dll.sub(2, byref(p))#通过库中的byref关键字来实现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].words)print (o.kws[1].words)print (o.len)•调用Windows API#导入ctypes模块from ctypes import *er32.MessageBoxW(0, '内容!', '标题', 0)#也可以用以下方式为API函数建立个别名后再进行调用MessageBox = er32.MessageBoxWMessageBox(0, '内容!', '标题', 0)运行结果预览。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
产生了同样的 exception,当你用 cdecl 调用约定去使用一个 stdcall 函数,反之亦然。
注意:本文中的代码例子使用 doctest 确保他们能够实际工作。一些代码例子在 linux 和 windows 以及苹果机上执行有一定的差别
注意:一些代码引用了 ctypes 的 c_int 类型。它是 c_long 在 32 位机子上的别名,你不应该 变得迷惑,如果你期望 的是 c_int 类型,实事上打印的是 c_long,它们实事上是相同的类型。
注意 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);
File "<stdin>", line 1, in ? ValueError: Procedure probably called with not enough arguments (4 bytes missing) >>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS Traceback (most recent call last):
内容: .加载动态链接库 .从已加载的 dll 中引用函数 .调用函数 1 .基本的数据类型 .调用函数 2 .用自己的数据类型调用函数 .确认需要的参数类型(函数原型) .返回值 .传递指针 .结构和联合 .结构或联合的对齐方式和字节的顺序 .结构和联合中的位 .数组 .指针 .类型转换 .未完成的类型 .回调函数 .访问 dlls 导出的值 .可变长度的数据类型 .bugs 将要做的和没有做的事情
找到正确的调用约定,你必须检查 c 头文件或者你想调用的函数的文档。
在 windows,ctypes 使用 win32 结构 exception 处理一般的保护错误阻止 crashes,当调用无 效的参数值
>>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS Traceback (most recent call last):
>>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX
<CDLL 'libc.so.6', handle ... at ...>
>>> libc = CDLL("libc.so.6") # doctest: +LINUX
>>> libc
# doctest: +LINUX
在调用带有参数的函数之前,我们必须学习更多的关于 ctypes 数据类型。
基础的数据类型 ctypes 定义了许多主要的 c 兼容有数据类型
数据类型请见 /log-21.html
使用它们和一个可选的正确的值去创建所有的这些类型 >>> c_int() c_long(0) >>> c_char_p("Hello, World") c_char_p('Hello, World') >>> c_ushort(-3) c_ushort(65533) >>>
<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: +WINDOWS Traceback (most recent call last):
windll 不 会 神 奇 的 自 已 去 选 择 一 个 , 你 必 须 显 式 确 认 GetModuleHandleA 或 者 GetModuleHandleW 去使用它们 去处理一般字符串或 unicode 字符串。 有时候,dll 导出函数名,python 无法识别 ,像"??2@YAPAXI@Z". 在这情况下,你必须使用 getattr 去使用这些函数
调用函数 你可调用这些函数,像其它的 python 函数一样,下面的例子使用 time()函数,它以秒为单 位返回从 unix 新纪元的系统时间 ,GetModuleHandleA()函数,返回一个 win32 模块句柄。
下面的例子用空指针调用函数(None 作为空指针)
>>> print libc.time(None) # doctest: +SKIP 1150640792 >>> print hex(windll.kernel32.GetMDOWS 0x1d000000 >>>
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") # doctest: +WINDOWS <_FuncPtr object at 0x...> >>>
在 windows 上,一些 dllS 不是导出函数名,而是以顺序,这些函数可以将这些数字当作 dll 对象的索引来使用 这些函数。
File "<stdin>", line 1, in ? WindowsError: exception: access violation reading 0x00000020 >>>
然而有很多种可能性会发生 crash,你使用 python 的 ctypes,你应该足够的小心。
None,integers,longs,byte strings 和 unicode string 是 python 内置对象,可以直接的作为这些 函数的参数 ,None 作为一个空指针,byte string 和 unicode string 当作一个内存块,它包含这些数据(char* 或者 wchar_t*) 。python 的 int 和 long 长整形作为 c int 类型,它们的值对应着 c 类型。
>>> print cdll.msvcrt # doctest: +WINDOWS <CDLL 'msvcrt', handle ... at ...> >>> libc = cdll.msvcrt # doctest: +WINDOWS >>>
windows 自动添加常用的.dll 文件后缀名 在 linux 上,需要使用包含扩展名的文件名来加载一个库,因此属性操作不能正常使用。 或 者使用 dll 加载器的 LoadLibrary 方法,或者通过 CDLL 构造函数创建一个 CDLL 的一个实例
ctypes 尝试阻止你以错误的参数数量或调用约定来调用函数。不幸的是,这些仅仅能在 windows 上工作 它在函数返回后不会去检查这栈,尽管在调用函数后有错误发生。
>>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS Traceback (most recent call last):
注:cdecl 和 stdcall 的区别请见 /log-20.html
>>> from ctypes import * >>> print windll.kernel32 # doctest: +WINDOWS <WinDLL 'kernel32', handle ... at ...>
File "<stdin>", line 1, in ? File "ctypes.py", line 239, in __getattr__ func = _StdcallFuncPtr(name, self) AttributeError: function 'MyOwnFunction' not found >>>00
>>> cdll.kernel32[1] # doctest: +WINDOWS <_FuncPtr object at 0x...> >>> cdll.kernel32[0] # doctest: +WINDOWS Traceback (most recent call last):