这是一些Windows下的例子。请注意msvcrt是包含大部分C函数的MS标准C库,并会使用cdecl调用惯例:
备注
通过cdll.msvcrt调用的标准C函数,可能会导致调用一个过时的,与当前Python所不兼容的函数。因此,请尽量使用标准的Python函数,而不要使用msvcrt模块。
/*ANSIversion*/HMODULEGetModuleHandleA(LPCSTRlpModuleName);/*UNICODEversion*/HMODULEGetModuleHandleW(LPCWSTRlpModuleName);windll不会通过这样的魔法手段来帮你决定选择哪一种函数,你必须显式的调用GetModuleHandleA或GetModuleHandleW,并分别使用字节对象或字符串对象作参数。
>>>getattr(cdll.msvcrt,"2@YAPAXI@Z")<_FuncPtrobjectat0x...>>>>Windows下,有些dll导出的函数没有函数名,而是通过其顺序号调用。对此类函数,你也可以通过dll对象的数值索引来操作这些函数。
>>>print(libc.rand())1804289383在Windows上,你可以调用GetModuleHandleA()函数,它返回一个win32模块句柄(将None作为唯一参数传入以使用NULL指针来调用它):
>>>cdll.kernel32.GetModuleHandleA(None)Traceback(mostrecentcalllast):File"
None、整数、字节串对象和(Unicode)字符串是仅有的可以直接作为这些函数调用的形参的原生Python对象。None将作为CNULL指针传入,字节串对象和字符串将作为指向包含其数据(char*或wchar_t*)的内存块的指针传入。Python整数将作为平台默认的Cint类型传入,它们的值会被截断以适应C类型的长度。
ctypes类型
C类型
Python类型
_Bool
bool(1)
char
单字符字节串对象
wchar_t
单字符字符串
int
unsignedchar
short
unsignedshort
unsignedint
long
unsignedlong
__int64或longlong
unsigned__int64或unsignedlonglong
size_t
time_t
float
double
longdouble
char*(以NUL结尾)
字节串对象或None
wchar_t*(以NUL结尾)
字符串或None
void*
int或None
所有这些类型都可以通过使用正确类型和值的可选初始值调用它们来创建:
>>>c_int()c_long(0)>>>c_wchar_p("Hello,World")c_wchar_p(140018365411392)>>>c_ushort(-3)c_ushort(65533)>>>由于这些类型是可变的,它们的值也可以在以后更改:
time()的C原型是time_ttime(time_t*)。由于time_t的类型可能不同于默认返回类型int,你应当指定restype属性:
>>>libc.time.argtypes=(POINTER(c_time_t),)调用该函数时如果要将NULL指针作为第一个参数,请使用None:
>>>print(libc.time(None))1150640792下面是一个更高级的示例,它使用了strchr()函数,该函数接收一个字符串指针和一个字符,并返回一个字符串指针:
有时候C函数接口可能由于要往某个地址写入值,或者数据太大不适合作为值传递,从而希望接收一个指针作为数据参数类型。这和传递参数引用类似。
这是一个简单的POINT结构体,它包含名称为x和y的两个变量,还展示了如何通过构造函数初始化结构体。
>>>fromctypesimport*>>>classPOINT(Structure):..._fields_=[("x",c_int),...("y",c_int)]...>>>point=POINT(10,20)>>>print(point.x,point.y)1020>>>point=POINT(y=5)>>>print(point.x,point.y)05>>>POINT(1,2,3)Traceback(mostrecentcalllast):File"
这是以一个RECT结构体,他包含了两个POINT,分别叫upperleft和lowerright:
>>>classRECT(Structure):..._fields_=[("upperleft",POINT),...("lowerright",POINT)]...>>>rc=RECT(point)>>>print(rc.upperleft.x,rc.upperleft.y)05>>>print(rc.lowerright.x,rc.lowerright.y)00>>>嵌套结构体可以通过几种方式构造初始化:
>>>print(POINT.x)
创建数组类型的推荐方式是使用一个类型乘以一个正数:
TenPointsArrayType=POINT*10下面是一个构造的数据案例,结构体中包含了4个POINT和一些其他东西。
>>>fromctypesimport*>>>classPOINT(Structure):..._fields_=("x",c_int),("y",c_int)...>>>classMyStruct(Structure):..._fields_=[("a",c_int),...("b",c_float),...("point_array",POINT*4)]>>>>>>print(len(MyStruct().point_array))4>>>和平常一样,通过调用它创建实例:
arr=TenPointsArrayType()forptinarr:print(pt.x,pt.y)以上代码会打印几行00,因为数组内容被初始化为0.
也能通过指定正确类型的数据来初始化:
>>>i=c_int(99)>>>pi.contents=i>>>pi.contentsc_long(99)>>>指针对象也可以通过整数下标进行访问:
>>>pi[0]99>>>通过整数下标赋值可以改变指针所指向的真实内容:
>>>print(i)c_long(99)>>>pi[0]=22>>>print(i)c_long(22)>>>使用0以外的索引也是合法的,但是你必须确保知道自己为什么这么做,就像C语言中:你可以访问或者修改任意内存内容。通常只会在函数接收指针是才会使用这种特性,而且你知道这个指针指向的是一个数组而不是单个值。
可以给指针内容赋值为None将其设置为Null
>>>fromctypesimport*>>>classcell(Structure):...pass...>>>cell._fields_=[("name",c_char_p),...("next",POINTER(cell))]>>>让我们试试。我们定义两个cell实例,让它们互相指向对方,然后通过指针链式访问几次:
首先,你必须为回调函数创建一个类,这个类知道调用约定,包括返回值类型以及函数接收的参数类型及个数。
这些工厂函数的第一个参数是返回值类型,回调函数的参数类型作为剩余参数。
这里展示一个使用标准C库的qsort()函数例子,使用它在一个回调函数的协助下对条目进行排序。qsort()将被用来给一个整数的数组排序:
>>>IntArray5=c_int*5>>>ia=IntArray5(5,1,7,33,99)>>>qsort=libc.qsort>>>qsort.restype=None>>>qsort()被调用时必须传入一个指向要排序的数据的指针、数据数组中的条目数、每条目的大小以及一个指向比较函数即回调函数的指针。回调函数将附带两个指向条目的指针进行调用,如果第一个条目小于第二个条目则它必须返回一个负整数,如果两者相等则返回零,在其他情况下则返回一个正整数。
所以,我们的回调函数要接收两个整数指针,返回一个整数。首先我们创建回调函数的类型
>>>CMPFUNC=CFUNCTYPE(c_int,POINTER(c_int),POINTER(c_int))>>>首先,这是一个简单的回调,它会显示传入的值:
>>>defpy_cmp_func(a,b):...print("py_cmp_func",a[0],b[0])...return0...>>>cmp_func=CMPFUNC(py_cmp_func)>>>结果:
>>>qsort(ia,len(ia),sizeof(c_int),cmp_func)py_cmp_func51py_cmp_func3399py_cmp_func733py_cmp_func57py_cmp_func17>>>现在我们可以比较两个元素并返回有用的结果了:
>>>defpy_cmp_func(a,b):...print("py_cmp_func",a[0],b[0])...returna[0]-b[0]...>>>>>>qsort(ia,len(ia),sizeof(c_int),CMPFUNC(py_cmp_func))py_cmp_func51py_cmp_func3399py_cmp_func733py_cmp_func17py_cmp_func57>>>我们可以轻易地验证,现在数组是有序的了:
>>>foriinia:print(i,end="")...1573399>>>这些工厂函数可以当作装饰器工厂,所以可以这样写:
>>>@CFUNCTYPE(c_int,POINTER(c_int),POINTER(c_int))...defpy_cmp_func(a,b):...print("py_cmp_func",a[0],b[0])...returna[0]-b[0]...>>>qsort(ia,len(ia),sizeof(c_int),py_cmp_func)py_cmp_func51py_cmp_func3399py_cmp_func733py_cmp_func17py_cmp_func57>>>备注
对文档中这个值的解释说明
>>>FrozenTable=POINTER(struct_frozen)>>>table=FrozenTable.in_dll(pythonapi,"_PyImport_FrozenBootstrap")>>>由于table是指向struct_frozen数组的指针,我们可以遍历它,只不过需要自己判断循环是否结束,因为指针本身并不包含长度。它早晚会因为访问到野指针或者什么的把自己搞崩溃,所以我们最好在遇到NULL后就让它退出循环:
>>>foritemintable:...ifitem.nameisNone:...break...print(item.name.decode("ascii"),item.size)..._frozen_importlib31764_frozen_importlib_external41499zipimport12345>>>Python的冻结模块和冻结包(由负size成员表示)并不是广为人知的事情,它们仅仅用于实验。例如,可以使用import__hello__尝试一下这个功能。
比如下面的例子:
>>>fromctypesimport*>>>classPOINT(Structure):..._fields_=("x",c_int),("y",c_int)...>>>classRECT(Structure):..._fields_=("a",POINT),("b",POINT)...>>>p1=POINT(1,2)>>>p2=POINT(3,4)>>>rc=RECT(p1,p2)>>>print(rc.a.x,rc.a.y,rc.b.x,rc.b.y)1234>>>#现在交换这两个>>>rc.a,rc.b=rc.b,rc.a>>>print(rc.a.x,rc.a.y,rc.b.x,rc.b.y)3434>>>嗯。我们预想应该打印3412。但是为什么呢这是rc.a,rc.b=rc.b,rc.a这行代码展开后的步骤:
>>>temp0,temp1=rc.b,rc.a>>>rc.a=temp0>>>rc.b=temp1>>>注意temp0和temp1对象始终引用了对象rc的内容。然后执行rc.a=temp0会把temp0的内容拷贝到rc的空间。这也改变了temp1的内容。最终导致赋值语句rc.b=temp1没有产生预想的效果。
记住,访问被包含在结构体、联合、数组中的对象并不会将其复制出来,而是得到了一个代理对象,它是对根对象的内部内容的一层包装。
下面是另一个可能和预期有偏差的例子:
>>>short_array=(c_short*4)()>>>print(sizeof(short_array))8>>>resize(short_array,4)Traceback(mostrecentcalllast):...ValueError:minimumsizeis8>>>resize(short_array,32)>>>sizeof(short_array)32>>>sizeof(type(short_array))8>>>这非常好,但是要怎么访问数组中额外的元素呢?因为数组类型已经定义包含4个元素,导致我们访问新增元素时会产生以下错误:
在编译型语言中,动态链接库会在编译、链接或者程序运行时访问。
ctypes.util模块提供了一个函数,可以帮助确定要加载的库。
尝试寻找一个库然后返回其路径名,name是库名称,且去除了lib等前缀和.so、.dylib、版本号等后缀(这是posix连接器-l选项使用的格式)。如果没有找到对应的库,则返回None。
确切的功能取决于系统。
在3.6版本发生变更:在Linux上,如果其他方式找不到的话,会使用环境变量LD_LIBRARY_PATH搜索动态链接库。
这是一些例子:
有很多方式可以将动态链接库加载到Python进程。其中之一是实例化以下类的其中一个:
该类的实例代表已加载的共享库。这些库中的函数使用标准的C调用约定,并被预期会返回int。
参见
这个类的实例代表已加载的共享库,这些库中的函数使用stdcall调用约定,并且默认预期返回int。
所以,它只在直接调用PythonC接口函数的时候有用。
所有这些类均可通过附带至少一个参数即共享库的路径名来调用它们进行实例化。如果你有一个对应已加载共享库的现有句柄,可以将其作为handle具名形参传入,否则会使用下层平台的dlopen()或LoadLibrary()函数将库加载到进程中,并获取对应的句柄。
winmode形参用于在Windows上指定库的加载方式(因为mode会被忽略)。它接受任何对Win32APILoadLibraryEx旗标形参来说合法的值。当被省略时,默认使用表示最安全的DLL加载的旗标,这将避免DLL劫持等问题。传入DLL的完整路径是确保正确加载库及其依赖的最安全的方式。
在3.8版本发生变更:增加了winmode参数。
用于mode参数的标识值。在此标识不可用的系统上,它被定义为整数0。
Flagtouseasmodeparameter.Onplatformswherethisisnotavailable,itisthesameasRTLD_GLOBAL.
加载动态链接库的默认模式。在OSX10.3上,它是RTLD_GLOBAL,其余系统上是RTLD_LOCAL。
这些类的实例没有共用方法。动态链接库的导出函数可以通过属性或者索引的方式访问。注意,通过属性的方式访问会缓存这个函数,因而每次访问它时返回的都是同一个对象。另一方面,通过索引访问,每次都会返回一个新的对象:
用于访问库的系统句柄。
传入构造函数的库名称。
__getattr__()具有特殊的行为:它允许通过一个作为库加载器实例的属性访问共享库来加载它。访问结果会被缓存,因此每次重复的属性访问都会返回相同的库。
加载一个共享库到进程中并将其返回。此方法总是返回一个新的库实例。
可用的预制库加载器有如下这些:
要直接访问CPythonapi,可以使用一个现成的Python共享库对象:
在加载的库上访问一个函数将引发一个审计事件ctypes.dlsym并附带参数library(库对象)和name(以字符串或整数表示的符号名称).
在只有库句柄而非对象可用的情况下,访问函数会引发一个审计事件ctypes.dlsym/handle并附带参数handle(原始库句柄)和name。
正如前一节的说明,外部函数可作为已加载共享库的属性来访问。用此方式创建的函数对象默认接受任意数量的参数,接受任意ctypes数据实例作为参数,并且返回库加载器所指定的默认结果类型。
外部函数的实例也是兼容C的数据类型;它们代表C函数指针。
此行为可通过对外部函数对象的特殊属性赋值来自定义。
分配一个ctypes类型来指定外部函数的结果类型。使用None来表示void,即不返回任何结果的函数。
赋值为一个ctypes类型的元组来指定函数所接受的参数类型。使用stdcall调用规范的函数只能附带与此元组长度相同数量的参数进行调用;使用C调用规范的函数还可接受额外的未指明参数。
将一个Python函数或其他可调用对象赋值给此属性。该可调用对象将附带三个及以上的参数被调用。
result是外部函数返回的结果,由restype属性指明。
func是外部函数对象本身,这样就允许重新使用相同的可调用对象来对多个函数进行检查或后续处理。
arguments是一个包含最初传递给函数调用的形参的元组,这样就允许对所用参数的行为进行特别处理。
此函数所返回的对象将会由外部函数调用返回,但它还可以在外部函数调用失败时检查结果并引发异常。
此异常会在外部函数无法对某个传入参数执行转换时被引发。
在Windows上,当外部函数调用引发一个系统异常时(例如由于访问冲突),它将被捕获并被替换为适当的Python异常。此外,还将引发一个审计事件ctypes.set_exception并附带参数code,以允许审计钩子将原异常替换为它自己的异常。
某些发起外部函数调用的方式可能会引发一个审计事件ctypes.call_function并附带参数functionpointer和arguments。
返回的函数原型会创建使用stdcall调用约定的函数。该函数在调用过程中将会释放GIL。use_errno和use_last_error具有与上文相同的含义。
返回的函数原型会创建使用Python调用约定的函数。该函数在调用过程中将不会释放GIL。
这些工厂函数所创建的函数原型可通过不同的方式来实例化,具体取决于调用中的类型与数量:
在指定地址上返回一个外部函数,地址值必须为整数。
基于Pythoncallable创建一个C可调用函数(回调函数)。
返回由一个共享库导出的外部函数。func_spec必须为一个2元组(name_or_ordinal,library)。第一项是字符串形式的所导出函数名称,或小整数形式的所导出函数序号。第二项是该共享库实例。
返回将调用一个COM方法的外部函数。vtbl_index虚拟函数表中的索引。name是COM方法的名称。iid是可选的指向接口标识符的指针,它被用于扩展的错误报告。
COM方法使用特殊的调用约定:除了在argtypes元组中指定的形参,它们还要求一个指向COM接口的指针作为第一个参数。
可选的paramflags形参会创建相比上述特性具有更多功能的外部函数包装器。
此元组中的每一项都包含有关形参的更多信息,它必须为包含一个、两个或更多条目的元组。
第一项是包含形参指令旗标组合的整数。
指定函数的一个输入形参。
输出形参。外部函数会填入一个值。
默认为整数零值的输入形参。
可选的第二项是字符串形式的形参名称。如果指定此项,则可以使用该形参名称来调用外部函数。
可选的第三项是该形参的默认值。
>>>fromctypesimportc_int,WINFUNCTYPE,windll>>>fromctypes.wintypesimportHWND,LPCWSTR,UINT>>>prototype=WINFUNCTYPE(c_int,HWND,LPCWSTR,LPCWSTR,UINT)>>>paramflags=(1,"hwnd",0),(1,"text","Hi"),(1,"caption","Hellofromctypes"),(1,"flags",0)>>>MessageBox=prototype(("MessageBoxW",windll.user32),paramflags)现在MessageBox外部函数可以通过以下方式来调用:
>>>fromctypesimportPOINTER,WINFUNCTYPE,windll,WinError>>>fromctypes.wintypesimportBOOL,HWND,RECT>>>prototype=WINFUNCTYPE(BOOL,HWND,POINTER(RECT))>>>paramflags=(1,"hwnd"),(2,"lprect")>>>GetWindowRect=prototype(("GetWindowRect",windll.user32),paramflags)>>>带有输出形参的函数如果输出形参存在单一值则会自动返回该值,或是当输出形参存在多个值时返回包含这些值的元组,因此当GetWindowRect被调用时现在将返回一个RECT实例。
返回一个ctypes类型的对齐要求。obj_or_type必须为一个ctypes类型或实例。
返回指向obj的轻量指针,该对象必须为一个ctypes类型的实例。offset默认值为零,且必须为一个将被添加到内部指针值的整数。
byref(obj,offset)对应于这段C代码:
(((char*)&obj)+offset)返回的对象只能被用作外部函数调用形参。它的行为类似于pointer(obj),但构造起来要快很多。
此函数类似于C的强制转换运算符。它返回一个type的新实例,该实例指向与obj相同的内存块。type必须为指针类型,而obj必须为可以被作为指针来解读的对象。
init_or_size必须是一个指明数组大小的整数,或者是一个将被用来初始化数组条目的字节串对象。
如果将一个字节串对象指定为第一个参数,则将使缓冲区大小比其长度多一项以便数组的最后一项为一个NUL终结符。可以传入一个整数作为第二个参数以允许在不使用字节串长度的情况下指定数组大小。
init_or_size必须是一个指明数组大小的整数,或者是一个将被用来初始化数组条目的字符串。
如果将一个字符串指定为第一个参数,则将使缓冲区大小比其长度多一项以便数组的最后一项为一个NUL终结符。可以传入一个整数作为第二个参数以允许在不使用字符串长度的情况下指定数组大小。
此函数是一个允许使用ctypes实现进程内COM服务器的钩子。它将由_ctypes扩展所导出的DllCanUnloadNow函数来调用。
此函数是一个允许使用ctypes实现进程内COM服务器的钩子。它将由_ctypes扩展DLL所导出的DllGetClassObject函数来调用。
尝试寻找一个库并返回路径名称。name是库名称并且不带任何前缀如lib以及后缀如.so,.dylib或版本号(形式与posix链接器选项-l所用的一致)。如果找不到库,则返回None。
返回Python以及扩展模块所使用的VC运行时库的文件名。如果库名称无法确定,则返回None。
如果你需要通过调用free(void*)来释放内存,例如某个扩展模块所分配的内存,重要的一点是你应当使用分配内存的库中的函数。
返回错误码code的文本描述。如果未指定错误码,则会通过调用WindowsAPI函数GetLastError来获取最近的错误码。
返回Windows在调用线程中设置的最近的错误码。此函数会直接调用WindowsGetLastError()函数,它并不返回错误码的ctypes私有副本。
返回调用线程中系统LastError变量的ctypes私有副本的当前值。
与标准Cmemmove库函数相同:将count个字节从src拷贝到dst。dst和src必须为整数或可被转换为指针的ctypes实例。
与标准Cmemset库函数相同:将位于地址dst的内存块用count个字节的c值填充。dst必须为指定地址的整数或ctypes实例。
创建并返回一个新的ctypes指针类型。指针类型会被缓存并在内部重复使用,因此重复调用此函数耗费不大。type必须为ctypes类型。
创建一个新的指针实例,指向obj。返回的对象类型为POINTER(type(obj))。
注意:如果你只是想向外部函数调用传递一个对象指针,你应当使用更为快速的byref(obj)。
此函数可改变obj的内部内存缓冲区大小,其参数必须为ctypes类型的实例。没有可能将缓冲区设为小于对象类型的本机大小值,该值由sizeof(type(obj))给出,但将缓冲区加大则是可能的。
在调用线程中将系统LastError变量的ctypes私有副本的当前值设为value并返回之前的值。
返回ctypes类型或实例的内存缓冲区以字节表示的大小。其功能与Csizeof运算符相同。
返回位于void*ptr的字节串。如果指定了size,它将被用作字节串的大小,否则将假定字节串以零值结尾。
返回位于void*ptr的宽字符串。如果指定了size,它将被用作字符串的字符数量,否则将假定字符串以零值结尾。
此方法会使用address所指定的内存返回一个ctypes类型的实例,该参数必须为一个整数。
所有ctypes数据类型都带有这个类方法的默认实现,它通常会返回obj,如果该对象是此类型的实例的话。某些类型也能接受其他对象。
此方法返回一个由共享库导出的ctypes类型。name为导出数据的符号名称,library为所加载的共享库。
ctypes数据类型的通用实例变量:
这个只读变量在ctypes数据实例自身已分配了内存块时为真值,否则为假值。
这个成员或者为None,或者为一个包含需要保持存活以使内存块的内存保持有效的Python对象的字典。这个对象只是出于调试目的而对外公开;绝对不要修改此字典的内容。
实例拥有一个属性:
这个属性包含实例的实际值。对于整数和指针类型,它是一个整数,对于字符类型,它是一个单字符字符串对象或字符串,对于字符指针类型,它是一个Python字节串对象或字符串。
这些是基本ctypes数据类型:
代表Csignedchar数据类型,并将值解读为一个小整数。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Cchar数据类型,并将值解读为单个字符。该构造器接受一个可选的字符串初始值,字符串的长度必须恰好为一个字符。
当指向一个以零为结束符的字符串时代表Cchar*数据类型。对于通用字符指针来说也可能指向二进制数据,必须要使用POINTER(c_char)。该构造器接受一个整数地址,或者一个字节串对象。
代表Cdouble数据类型。该构造器接受一个可选的浮点数初始值。
代表Cfloat数据类型。该构造器接受一个可选的浮点数初始值。datatype.Theconstructoracceptsanoptionalfloatinitializer.
代表Csignedlong数据类型。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Csignedlonglong数据类型。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Csignedshort数据类型。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Csize_t数据类型。
代表Cssize_t数据类型。
Addedinversion3.2.
代表Ctime_t数据类型。
Addedinversion3.12.
代表Cunsignedchar数据类型,它将值解读为一个小整数。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Cunsignedlong数据类型。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Cunsignedlonglong数据类型。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Cunsignedshort数据类型。该构造器接受一个可选的整数初始值;不会执行溢出检查。
代表Cvoid*类型。该值被表示为整数形式。该构造器接受一个可选的整数初始值。
代表Cwchar_t数据类型,并将值解读为一单个字符的unicode字符串。该构造器接受一个可选的字符串初始化器,字符串的长度必须恰好为一个字符。
代表Cwchar_t*数据类型,它必须为指向以零为续签符的宽字符串的指针。该构造器接受一个整数地址,或一个字符串。
代表Cbool数据类型(更准确地说,是C99_Bool)。它的值可以为True或False,并且该构造器接受任何具有逻辑值的对象。
代表一个HRESULT值,它包含某个函数或方法调用的成功或错误信息。
ctypes.wintypes模块提供了其他许多Windows专属的数据类型,例如HWND,WPARAM或DWORD。还定义了一些有用的结构体如MSG或RECT。
本机字节序的联合所对应的抽象基类。
大端字节序的联合所对应的抽象基类。
Addedinversion3.11.
小端字节序的联合所对应的抽象基类。
大端字节序的结构体所对应的抽象基类。
小端字节序的结构体所对应的抽象基类。
非本机字节序的结构体和联合不能包含指针类型字段,或任何其他包含指针类型字段的数据类型。
本机字节序的结构体所对应的抽象基类。
一个定义结构体字段的序列。其中的条目必须为2元组或3元组。元组的第一项是字段名称,第二项指明字段类型;它可以是任何ctypes数据类型。
字段名称在一个结构体或联合中必须唯一。不会检查这个唯一性,但当名称出现重复时将只有一个字段可被访问。
一个可选的小整数,它允许覆盖结构体在针对内存执行打包或解包时的对齐方式。将该属性设为0与完全不设置它效果相同。
Addedinversion3.13.
以下是一个示例类型(Windows):
数组的抽象基类。
指明数组中每个元素的类型。
Array子类构造器可接受位置参数,用来按顺序初始化元素。
私有对象,指针的抽象基类。
指明所指向的类型。
返回指针所指向的对象。对此属性赋值会使指针改为指向所赋值的对象。