如何从ctype结构构建Python字符串?
我正在使用ctypes,并且定义了一个结构体来传递参数。
class my_struct(ctypes.Structure):
_fields_ = [ ("buffer", ctypes.c_char * BUFSIZE),
("size", ctypes.c_int )]
然后我用下面的代码调用C语言的函数,但我不知道如何从我创建的结构体中生成一个字符串。
class Client():
def __init__(self):
self.__proto = my_struct()
self.client = ctypes.cdll.LoadLibrary(r"I:\bin\client.dll")
def version(self):
ret = self.client.execute(ctypes.byref(self.__proto))
my_string = self.__proto.buffer[:self.__proto.size]
我想用缓冲区的前n个字节来创建一个Python字符串(这个缓冲区里包含NULL字符,但我需要处理这种情况,如果有必要的话,要用/0x00字符来创建字符串)。这个赋值
my_string = self.__proto.buffer[:self.__proto.size]
没有成功,因为如果出现0x00,它会截断字符串。欢迎任何想法。提前谢谢。
2 个回答
0
我觉得你需要在你的 my_struct 里面发送一个指向 C 字符串的指针,而不是直接发送 C 字符串,因为 C 字符串是以空字符结束的。你可以试着这样做:
import ctypes
BUFSIZE = 10
class my_struct(ctypes.Structure):
_fields_ = [ ("buffer", ctypes.POINTER(ctypes.c_char)),
("size", ctypes.c_int )]
cstr = (ctypes.c_char * BUFSIZE)()
proto = my_struct(cstr)
3
你的问题在于,ctypes
会对 char
数组做一些自动处理,把它们转换成以 NUL 结尾的字符串。你可以通过使用 ctypes.c_byte
类型来避免这种自动处理,而不是使用 ctypes.c_char
,然后用 ctypes.string_at
来获取字符串的值。为了让访问结构体的成员更方便,你可以在结构体类中添加一个辅助属性,比如:
import ctypes
BUFSIZE = 1024
class my_struct(ctypes.Structure):
_fields_ = [ ("_buffer", ctypes.c_byte * BUFSIZE),
("size", ctypes.c_int )]
def buffer():
def fget(self):
return ctypes.string_at(self._buffer, self.size)
def fset(self, value):
size = len(value)
if size > BUFSIZE:
raise ValueError("value %s too large for buffer",
repr(value))
self.size = size
ctypes.memmove(self._buffer, value, size)
return property(fget, fset)
buffer = buffer()
proto = my_struct()
proto.buffer = "here\0are\0some\0NULs"
print proto.buffer.replace("\0", " ")