python ctypes模块中文帮助文档
- 格式:pdf
- 大小:163.38 KB
- 文档页数:23
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之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模块调用其它如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结构体的指针变量。
内容:.加载动态链接库.从已加载的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 手册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 在 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进行交互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)运行结果预览。
PythonOCC(OpenCascade Community Edition)是一个基于Python的开源CAD/CAE/PLM软件开发评台,它提供了一系列功能强大的工具和库,可以帮助用户快速实现CAD(Computer-Aided Design,计算机辅助设计)、CAE(Computer-Aided Engineering,计算机辅助工程)、PLM(Product Lifecycle Management,产品生命周期管理)等相关领域的开发需求。
PythonOCC中文参考手册是PythonOCC的重要文档之一,它为用户提供了全面的PythonOCC相关信息,帮助用户更好地理解和应用PythonOCC。
一、PythonOCC简介PythonOCC是基于开源CAD内核OpenCascade的Python封装,它提供了一系列可以用于CAD/CAE/PLM软件开发的Python接口和工具。
PythonOCC的主要特点包括开源免费、功能强大、易于学习和使用等。
通过PythonOCC,用户可以利用Python语言的简单易用和OpenCascade内核的强大功能,快速开发出符合自身需求的CAD/CAE/PLM软件,为工程设计和制造领域的开发者提供了一个高效便捷的开发评台。
二、PythonOCC中文参考手册的重要性PythonOCC中文参考手册是PythonOCC的冠方文档,它包含了PythonOCC库的详细说明、使用方法、示例代码等。
PythonOCC中文参考手册的重要性主要体现在以下几个方面:1.为用户提供了全面的PythonOCC相关信息PythonOCC中文参考手册为用户提供了全面的PythonOCC相关信息,涵盖了PythonOCC库的所有内容和功能。
用户可以通过阅读PythonOCC中文参考手册,了解PythonOCC的各种功能和接口,并快速掌握如何使用PythonOCC进行CAD/CAE/PLM软件开发。
python文档之查看帮助文档方法
准备
使用time模块,使用time模块的localtime函数,使用range类
在已经分清模块,函数,类的情况下开始测试
方法一
在python命令行输入以下内容
help(time)#很详细的模块文档
help(time.localtime())#很详细的函数文档
help(range)#很详细的类的文档
1
2
3方法二
在python命令行输入以下内容
print(time.__doc__)#较详细的模块文档
print(time.localtime().__doc__)#较详细的函数文档
print(range.__doc__)#较详细的类的文档
1
2
3方法三
在python命令行输入以下内容
print(dir(time))#简略的模块函数显示
print(dir(time.localtime()))#简略的函数参数显示
print(dir(range))#简略的类构造函数参数显示
1
2
3方法四
在python命令行中输入help(),然后再次输入time,可以获得很详细的模块文档
或者输入time.localtime,可以获得简略的函数参数显示
或者输入range,可以获得很详细的类的文档
好了,我讲明白了….。
python与C语⾔调⽤模块ctypes的详解ctypes是python的⼀个函数库,提供和C语⾔兼容的数据类型,可以直接调⽤动态链接库中的导出函数。
为了使⽤ctypes,必须依次完成以下步骤:加载动态链接库将python对象转换成ctypes所能识别的参数使⽤ctypes所能识别的参数调⽤动态链接库中的函数动态链接库加载⽅式有三种:cdllwindlloledll它们的不同之处在于:动态链接库中的函数所遵守的函数调⽤⽅式(calling convention)以及返回⽅式有所不同。
cdll⽤于加载遵循cdecl调⽤约定的动态链接库,windll⽤于加载遵循stdcall调⽤约定的动态链接库,oledll与windll完全相同,只是会默认其载⼊的函数统⼀返回⼀个WindowsHRESULT错误编码。
函数调⽤约定:函数调⽤约定指的是函数参数⼊栈的顺序、哪些参数⼊栈、哪些通过寄存器传值、函数返回时栈帧的回收⽅式(是由调⽤者负责清理,还是被调⽤者清理)、函数名称的修饰⽅法等等。
常见的调⽤约定有cdecl和stdcall两种。
在《程序cdecl规定函数参数列表以从右到左的⽅式⼊栈,且由函数的调⽤者负责清除栈帧上的参数。
stdcall的参数⼊栈⽅式与cdecl⼀致,但函数返回时是由被调⽤者⾃⼰负责清理栈帧。
⽽且stdcall是Win32 API函数所使⽤的调⽤约定。
例⼦:Linux下:或者:其他例⼦:⼀个完整的例⼦:1,编写动态链接库// filename: foo.c#include "stdio.h"char* myprint(char *str){puts(str);return str;}float add(float a, float b){return a + b;}将foo.c编译为动态链接库:gcc -fPIC -shared foo.c -o foo.so2.使⽤ctypes调⽤foo.so#coding:utf8#FILENAME:foo.pyfrom ctypes import *foo = CDLL('./foo.so')myprint = foo.myprintmyprint.argtypes = [POINTER(c_char)] # 参数类型为char指针myprint.restype = c_char_p # 返回类型为char指针res = myprint('hello ctypes')print(res)add = foo.addadd.argtypes = [c_float, c_float] # 参数类型为两个floatadd.restype = c_float # 返回类型为floatprint(add(1.3, 1.2))执⾏:[jingjiang@iZ255w0dc5eZ test]$ python2.6 foo.pyhello ctypeshello ctypes2.5ctypes数据类型和C数据类型对照表查找动态链接库>>> from ctypes.util import find_library>>> find_library("m")'libm.so.6'>>> find_library("c")'libc.so.6'>>> find_library("bz2")'libbz2.so.1.0'函数返回类型函数默认返回 C int 类型,如果需要返回其他类型,需要设置函数的 restype 属性。
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类的对象。
`ctypes` 是 Python 的一个库,它提供了一种方便的方法来调用动态链接库(DLL)或共享对象(.so)中的函数。
这在你需要使用 C 或 C++ 写的库时非常有用。
以下是一些 `ctypes` 的基本用法:1. 首先,你需要导入 `ctypes` 模块:```pythonimport ctypes```2. 然后,你需要定义你将要调用的动态链接库或共享对象的名称和路径。
例如,如果你的库名为 `mylib.dll`(在 Windows 上)或`libmylib.so`(在 Linux 上),你可以这样定义:```pythonmylib = ctypes.CDLL('mylib.dll') # 在 Windows 中mylib = ctypes.CDLL('libmylib.so') # 在 Linux 中```3. 现在,你可以使用 `mylib` 对象来调用你的 C 或 C++ 函数。
首先,你需要知道函数的名称,然后你需要知道函数的参数类型和返回类型。
这些信息都可以从你的 C 或 C++ 代码的文档中获取。
例如,假设你有一个名为 `add_numbers` 的函数,它接受两个`int` 参数并返回一个 `int` 值。
你可以这样调用它:```pythonresult = mylib.add_numbers(2, 3) # result 将会是 5```4. 如果你的函数是一个复杂的多参数函数,或者返回一个复杂的数据类型,你可能需要使用 `ctypes` 的更高级的特性。
例如,假设你的函数接受一个指向结构体的指针作为第一个参数,你可以这样做:```pythonclass MyStruct(ctypes.Structure):_fields_ = [("field1", ctypes.c_int), ("field2", ctypes.c_float)]my_struct = MyStruct()my_struct.field1 = 2my_struct.field2 = 3.14plex_function(my_struct, 42) # 调用一个接受MyStruct 指针和 int 值的函数```5. 对于返回复杂数据类型的函数,你可以使用`ctypes` 的`c_void_p` 类型来接收返回的数据,然后根据需要解析它。
pythonctypes中文帮助文档15.17。
ctypes- 用于Python的外部函数库2.5版中的新功能。
ctypes是Python的外部函数库。
它提供C兼容的数据类型,并允许在DLL或共享库中调用函数。
它可以用于在纯Python中包装这些库。
15.17.1。
ctypes教程注意:本教程中的代码示例doctest用于确保它们实际工作。
由于某些代码示例在Linux,Windows或Mac OS X下的行为不同,因此它们在注释中包含doctest指令。
注意:某些代码示例引用了ctypes c_int类型。
此类型是c_long32位系统上类型的别名。
因此,c_long如果您打算如果打印,则不应该感到困惑c_int- 它们实际上是相同的类型。
15.17.1.1。
加载动态链接库ctypes导出cdll,以及Windows windll和oledll对象,用于加载动态链接库。
您可以通过访问它们作为这些对象的属性来加载库。
cdll加载使用标准cdecl调用约定导出函数的库,而windll库使用stdcall 调用约定调用函数。
oledll还使用stdcall调用约定,并假定函数返回Windows HRESULT错误代码。
错误代码用于WindowsError在函数调用失败时自动引发异常。
以下是Windows的一些示例。
注意,它msvcrt是包含大多数标准C函数的MS标准C库,并使用cdecl调用约定:1.>>> from ctypes import *2.>>> print windll.kernel323.<WinDLL 'kernel32', handle ... at ...>4.>>> print cdll.msvcrt5.<CDLL 'msvcrt', handle ... at ...>6.>>> libc = cdll.msvcrt7.>>>Windows会.dll自动附加常用的文件后缀。
Python使用ctypes模块调用DLL函数之传递数值、指针与字符串参数引言在Python语言中,可以使用ctypes模块调用其它如C++语言编写的动态链接库DLL文件中的函数,在提高软件运行效率的同时,也可以充分利用目前市面上各种第三方的DLL库函数,以扩充Python 软件的功能及应用领域,减少重复编写代码、重复造轮子的工作量,这也充分体现了Python语言作为一种胶水语言所特有的优势。
这次以具体的例子讲一下在Python中,如何使用ctypes模块调用DLL中的库函数。
本文的编程系统环境是win7 64位,Python使用的版本是python2.7.14。
由于DLL中函数中传递的参数类型比较多样化,拟打算分三次讲解这部分内容,这次先讲传递数值、指针与字符串参数的情况,后面再分两次讲解传递结构体、数值数组等类型的情况。
DLL文件的加载假定已经有了一个DLL文件“MyDll.dll”,其函数约定的调用方式为C调用(cdecl)方式,则Python中加载该dll文件的代码如下:其中,第1行是引入ctypes模块,第2行是采用C调用约定加载“MyDll.dll”文件,并将返回值赋给dll变量,后续调用该DLL文件中的函数时,会使用该变量定义要使用的具体函数。
另外,需要说明的是,若DLL函数的调用约定是标准调用约定(stdcall)方式,则DLL文件的加载代码改为如下:dll = WinDLL(''MyDll.dll'')DLL函数的调用——函数参数为数值情况如对于“MyDll.dll”文件中的函数add,其函数声明如下:该函数有两个int类型的输入参数数x和y,返回的两个数的和。
其C语言的实现代码如下:在Python中的调用方式如下:这个函数应该说是最简单的一个函数了,在第17行,直接使用第一步加载DLL后返回的名称dll,后面跟函数名字即可返回其值。
DLL函数的调用——函数参数为指针情况对于上面的函数改进为add2,其函数C语言的实现代码如下:此时函数有三个指向int类型的指针参数x、y、z,z为x和y的和。
Python调⽤DLL动态链接库——ctypes使⽤最近要使⽤python调⽤C++编译⽣成的DLL动态链接库,因此学习了⼀下ctypes库的基本使⽤。
ctypes是⼀个⽤于Python的外部函数库,它提供C兼容的数据类型,并允许在DLL或共享库中调⽤函数。
⼀、Python调⽤DLL⾥⾯的导出函数1.VS⽣成dll1.1 新建动态链接库项⽬1.2 在myTest.cpp中输⼊以下内容:// myTest.cpp : 定义 DLL 应⽤程序的导出函数。
//#include "stdafx.h"#define DLLEXPORT extern "C" __declspec(dllexport) //放在 #include "stdafx.h" 之后//两数相加DLLEXPORT int sum(int a, int b) {return a + b;}注意:导出函数前⾯要加 extern "C" __declspec(dllexport) ,这是因为ctypes只能调⽤C函数。
如果不⽤extern "C",构建后的动态链接库没有这些函数的符号表。
采⽤C++的⼯程,导出的接⼝需要extern "C",这样python中才能识别导出的函数。
1.3⽣成dll动态链接库因为我的python3是64位的,所以VS⽣成的dll要选择64位的,如下所⽰:点击标题栏的⽣成 -> ⽣成解决⽅案1.4 查看⽣成的dll动态链接库2.Python导⼊dll动态链接库⽤python将动态链接库导⼊,然后调⽤动态链接库的函数。
为此,新建main.py⽂件,输⼊如下内容:from ctypes import *#----------以下四种加载DLL⽅式皆可—————————# pDLL = WinDLL("./myTest.dll")# pDll = windll.LoadLibrary("./myTest.dll")# pDll = cdll.LoadLibrary("./myTest.dll")pDll = CDLL("./myTest.dll")#调⽤动态链接库函数res = pDll.sum(1,2)#打印返回结果print(res)运⾏结果如下所⽰:⼆、Python调⽤DLL⾥⾯的实例⽅法更新全局变量值1.VS⽣成dll1.1 添加 mainClass 类,内容如下:mainClass.h:#pragma onceextern int dta;class mainClass{public:mainClass();~mainClass();void produceData();};mainClass.cpp:#include "stdafx.h"#include "mainClass.h"int dta = 0;mainClass::mainClass(){}mainClass::~mainClass(){}void mainClass::produceData() {dta = 10;}1.2 更改 myTest.cpp 内容myTest.cpp:#include "stdafx.h"#define DLLEXPORT extern "C" __declspec(dllexport) //放在 #include "stdafx.h" 之后#include "mainClass.h"//返回实例⽅法⾥⾯更新数据后的值DLLEXPORT int getRandData() {mainClass dataClass = mainClass();dataClass.produceData();return dta;}1.3 ⽣成64位dll2.Python导⼊dll动态链接库明显可以看出,在C++⾥设置的全局变量的值已经从0变为10了,说明python可以通过调⽤dll⾥⾯的实例⽅法来更新全局变量值三、Python_ctypes 指定函数参数类型和返回类型前⾯两个例⼦C++动态链接库导出函数的返回类型都是int型,⽽Python 默认函数的参数类型和返回类型为 int 型,所以Python 理所当然的以为 dll导出函数返回了⼀个 int 类型的值。
【python基础】ctypes使⽤的变量、指针、引⽤和buffer 程序如下,学习关注点见备注内容# -*- coding: utf-8 -*-from ctypes import *import sysprint '-'*100python_str = 'tests中国⼈' # 中⽂占4字节print 'python_string', python_strprint 'len:', len(python_str) # 字符长度,中⽂占3个长度,不含类似于C语⾔的结束符print 'getsizeof', sys.getsizeof(python_str)# print 'byref', byref(python_str) # byref参数必须是ctypes类型# print 'sizeof', sizeof(python_str) # sizeof参数必须是ctypes类型print '-'*100c_str_p = c_char_p(python_str)print 'c_str_p', c_str_p# print 'len:', len(c_str_p) # pointer没有lenprint 'getsizeof', sys.getsizeof(c_str_p) # 整个对象在python中占⽤的字节数print 'sizeof', sizeof(c_str_p) # 指针地址占⽤的字节数print 'addressof', hex(addressof(c_str_p)) # 纯地址print 'byref', byref(c_str_p) # 引⽤指针print 'string_at', string_at(c_str_p) # 获取内容print 'string_at 0-4', string_at(c_str_p, 4) # 获取内容print '-'*100c_str_buffer = c_buffer(python_str)print 'c_str_buffer', c_str_bufferprint 'getsizeof', sys.getsizeof(c_str_buffer)print 'sizeof', sizeof(c_str_buffer) # 字节数,⼀个中⽂字符占3个字节,⼀个英⽂字符占1个字节,结束符占⼀个字节print 'addressof', hex(addressof(c_str_buffer)) # 纯地址print 'byref', byref(c_str_buffer) # 引⽤指针print 'c_str_buffer.value', c_str_buffer.value # 获取内容print 'c_str_buffer[:4]', c_str_buffer[:4] # 截取内容print '-'*100c_num_long = c_long(0xfff)print 'c_num_long', c_num_long # 对象本⾝print 'value', c_num_long.value # 值print 'sizeof', sizeof(c_num_long)print '-'*100c_num_int = c_int(123)print 'c_num_int', c_num_int # 对象本⾝print 'value', c_num_int.value # 值print 'sizeof', sizeof(c_num_int)print '-'*100c_num_int64 = c_int64(123)print 'c_num_int64', c_num_int64 # 对象本⾝print 'value', c_num_int64.value # 值print 'sizeof', sizeof(c_num_int64)运⾏结果C:\Python27\python.exe C:/code/cetc/engine/DistributedNode/test.py----------------------------------------------------------------------------------------------------python_string tests中国⼈len: 14getsizeof 47----------------------------------------------------------------------------------------------------c_str_p c_char_p('tests\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba')getsizeof 128sizeof 8addressof 0x24f8a10Lbyref <cparam 'P' (00000000024F8A10)>string_at tests中国⼈string_at 0-4 test----------------------------------------------------------------------------------------------------c_str_buffer <ctypes.c_char_Array_15 object at 0x00000000024F8A48> getsizeof 128sizeof 15addressof 0x24f8a90Lbyref <cparam 'P' (00000000024F8A90)>c_str_buffer.value tests中国⼈c_str_buffer[:4] test----------------------------------------------------------------------------------------------------c_num_long c_long(4095)value 4095sizeof 4----------------------------------------------------------------------------------------------------c_num_int c_long(123)value 123sizeof 4----------------------------------------------------------------------------------------------------c_num_int64 c_longlong(123L)value 123sizeof 8Process finished with exit code 0。