在以下这行语句里:
MessageBox(None, 'Hello World!', 'Hello World', 0)
括号中的就是函数的參数列表。
C语言编写的函数时,定义函数的參数是使用C语言的方式来定义,那么在Python里编程是使用Python定义的类型。这两者之间是有区别的,这样的区别主要体如今类型定义内存的方式不一样。比方大小不一样,就算大小一样。在Python里还有每一个对象的引用计数。比方字符串在Python里是表示为一个对象,这个对象不但拥有字符串占用内存的空间,还有这个字符串引用的次数。而在C语言里仅仅是表示拥有字符串占用内存的空间,没有引用的次数。
为了在Python里能把Python的类型定义的数据对象转换为C语言的格式,是须要通过ctypes定义的类型来实现转换。
在ctype里有几个Python的数据类型是默认转换的,比方None/int/bytes/string(unicode),默认的转换相应关系例如以下表:
Python类型 | C类型 |
None | NULL |
int | int |
bytes | char* |
string | char* |
unicode string | wchar_t* |
所以在上面MessageBox函数调用中,直接写入这些參数,就能够了,不会有报错。假设是其他的数据类型,就须要使用ctype库的类型来定义了。比方C语言里结构定义的类型,这样的类型的相应关系,例如以下表:
ctypes类型 | C语言类型 | Python类型 |
c_bool | _Bool | bool(1) |
c_char | char | 1个字节的bytes对象 |
c_wchar | wchar_t | 1个字节的字符串对象 |
c_byte | char | int |
c_ubyte | unsigned char | int |
c_short | short | int |
c_ushort | unsigned short | int |
c_int | int | int |
c_uint | unsigned int | int |
c_long | long | int |
c_ulong | unsigned long | int |
c_longlong | __int64 或long long | int |
c_ulonglong | unsigned __int64或unsigned long long | int |
c_size_t | size_t | int |
c_ssize_t | ssize_t 或Py_ssize_t | int |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_char_p | char* | bytes对象或None |
c_wchar_p | wchar_t | 字符串或None |
c_void_p | void* | int 或None |
通过上表的关系。就能够找到全部Python里与C语言里类型相关的描写叙述方式。这样就能够定义与之相相应的数据结构,然后把这些结构传递给函数,就能够实现相互交换数据。依据这些数据类型的定义,能够把前面的Hello World的样例改动例如以下:
#开发者:蔡军生(QQ:9073204) 深圳 2014-8-11
from ctypes import *
MessageBox = windll.user32.MessageBoxW
handle = c_void_p(0)
hello = c_wchar_p('Hello World!')
title = c_wchar_p('Hello World')
mb_flag = c_int(0)
res = MessageBox(handle, hello, title, mb_flag)
在这个样例里,第一个參数是父窗体的句柄,前面是使用None来表示,如今使用c_void_p(0)来表示;显示内容的字符串在前面是直接表示,如今使用c_wchar_p('Hello World!')类型来表示,这样是表示一个UNICODE字符串。最后一个參数是使用c_int(0)来表示给函数的标志,比方显示button方式、是否有图标显示等等。通过ctypes里提供的类型转换,就能够无缝地对接C语言标准的动态连接库。