python⾼级ctypes数据类型—字符串数组
字符串数组在ctypes中的⾏为更接近于C语⾔中的字符串数组,其需要采⽤⼆维数组的形式来实现,⽽不是Python中的⼀维数组。⾸先,需要通过c_char类型乘上⼀个数,得到⼀个字符串类型,⽽后将此类型再乘上⼀个数,就能得到可以包含多个字符串的字符串数组。例:((c_char * 10) * 3)()
上例即实例化了⼀个3字符串数组,每个字符串最⼤长度为10。对于C语⾔⽽⾔,上述的字符串数组实例可直接当做字符串指针传⼊C函数,其⾏为等同于在C中声明的char (*)[10]指针。下详细讨论Python中对此对象的处理。⾸先,字符串数组也是可迭代对象,可通过for 循环迭代取值,对于上例的对象,其for循环得到的每⼀个值,都是⼀个10个长度的字符串对象。这样的字符串对象有两个重要属性:value和raw。value属性得到是普通字符串,即忽略了字符串终⽌符号(即C中的\0)以后的所有内容的字符串,⽽raw字符串得到的是当前对象的全部字符集合,包括终⽌符号。也就是说,对于10个长度的字符串对象,其raw的结果就⼀定是⼀个10个长度的字符串。例:
for i in ((c_char * 10) * 3)():
print(i.value)
python获取数组长度print(i.raw)
上述代码中,i.value的输出全为空字符串(b’’),⽽对于i.raw,其输出则为b’\x00\x00…’,总共⼗个\x00。也就是说,value会忽略字符串终⽌符号后的所有字符,是最常⽤的取值⽅式,⽽raw得到不忽略终⽌字符的字符串。接下来讨论ctypes中对字符串对象的赋值⽅法。由于ctypes的字符串对象通过某个固定长度的字符串类实例化得到,故在赋值时,这样的字符串对象只可以接受等同于其声明长度的字符串对象作为替代值,这是普通Python字符串做不到的。要得到这样的定长字符串,需要⽤到ctypes的create_string_buffer函数。create_string_buffer函数⽤于创建固定长度的带缓冲字符串。其接受两个参数,第⼀参数为字符串,第⼆参数为⽬标长度,返回值即为被创建的定长度字符串对象,可以赋值给字符串数组中的某个对象。注意,create_string_buffer函数必须接受字节字符串作为其第⼀参数,在Python2中,普通的字符串就是字节字符串,⽽在Python3中,所有的字符串默认为Unicode字符串,故可以通过字符串的encode、decode⽅法进⾏编码⽅式的转化。encode⽅法可将Python3的str转为bytes,其中的encoding参数默认就是UTF-8,故⽆需给出任何参数即可调⽤。同理,bytes可通过decode⽅法,以默认参数将bytes转化为Python3的str,对于Python2⽽⾔,⽆需考虑此问题。例:
charList = ((c_char * 10) * 3)()
strList = ['aaa', 'bbb', 'ccc']
for i in range(3):
charList[i] =                create_string_buffer(strList[i].encode(), 10)
for i in charList:
print(i.value)
上述代码的核⼼在于,通过create_string_buffer函数创建了⼀个10长度的带缓冲字符串,其第⼆参数10⽤作指定长度,⽽其第⼀参数为⼀个通过encode⽅法转化成的bytes字符串,这样得到的对象即可赋值给⼀个10长度的字符串对象。注意,通过create_string_buffer函数创建的字符串对象,其长度必须严格等同于被赋值的字符串对象的声明长度,即如果声明的是10长度字符串,那么
create_string_buffer的第⼆参数就必须也是10,否则代码将抛出TypeError异常,提⽰出现了类型不⼀致。
在字符串数组的初始化过程中,这样的字符串对象也可作为初始化的参数。例:
strList = ['aaa', 'bbb', 'ccc']
charList = ((c_char * 10) *3)(*[create_string_de(), 10) for i in strList])
for i in charList:
print(i.value.decode())
上述代码将实例化与初始化合并,通过列表推导式得到了3个10长度的缓冲字符串,并使⽤星号展开,作为实例化的参数。则这样得到的charList效果等同于上例中通过依次赋值得到的字符串数组对象。最后通过for循环输出字符串对象的value属性(⼀个bytes字符串),且通过decode⽅法将bytes转化为str。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。