2011-02-22 2 views
5

내가하는 ctypes를 사용하고 난 매개 변수 그리고 ctype 구조체에서 파이썬 문자열을 어떻게 작성합니까?

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] 

나는 (버퍼는 NULL 문자가 포함하지만 난이 상황을 처리 및/× 00 문자 경우 모든 necesary로 문자열을 만들어야합니다) 버퍼의 처음 n 바이트를 사용하여 파이썬 문자열을 만들려고합니다. × 00가 나타나면

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

이 bacause 작동하지 않는 asignation 문자열을 자릅니다. 어떤 생각이라도 환영합니다. 미리 감사드립니다.

+0

파이썬 2.6.3에서는 버퍼와 같은 ctypes 배열을 만들었지 만 테스트 할 수 없습니다. 다음과 같은 구조 클래스를 만들 수 있습니다. 실제로 잘라 버리는 것을보십시오. 이렇게 : ar = (ctypes.c_char * 10)(); ar.value = "test"; assert ar [: 6] == 'test \ x00 \ x00'. 내가 놓친 게 있니? – aknuds1

답변

3

귀하의 문제가 ctypes 시도가 char 배열을 당신을 위해 몇 가지 마술을 할 것입니다, 자동 변환 NUL 종료 문자열로합니다. ctypes.c_char 대신 ctypes.c_byte 유형을 사용하고 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

C 문자열이 null로 끝나기 때문에 직접 C 문자열이 아닌 my_struct에 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

관련 문제