如何从ctype结构构建python字符串?

时间:2011-02-22 19:15:58

标签: python c string ctypes

我正在使用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 :(得分: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", " ")

答案 1 :(得分: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)