python ctypes模块中文帮助文档

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