2011-02-22 73 views
5

我使用的ctypes和我定義這個結構,以傳遞參數如何從ctype結構構建python字符串?

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個字節(緩衝區包含NULL字符,但我必須處理這種情況,並與/ 0×00字符,如果necesary建立一個字符串)創建一個Python字符串。灰色

my_string = self.__proto.buffer[:self.__proto.size] 

不起作用如果出現0x00,會截斷字符串。任何想法是受歡迎的。提前致謝。

+0

在Python 2.6.3中,我測試過創建一個類似於緩衝區的ctypes數組,但是我無法看到它實際上被截斷了。像這樣:ar =(ctypes.c_char * 10)(); ar.value =「test」; assert ar [:6] =='test \ x00 \ x00'。我錯過了什麼嗎? – aknuds1 2011-02-26 23:52:30

回答

3

您的問題是​​嘗試做一些魔法爲你char陣列,自動將它們變成NULL結尾的字符串。您可以使用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", " ") 
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) 
+0

我看到你正在嘗試做什麼,但是如果OP所連接的庫所期望的結構具有直接嵌入在結構中的緩衝區,那麼這是不正確的。 – llasram 2011-03-18 13:11:40