2012-02-06 2 views
0

공유 라이브러리에 바인딩하기 위해 Python의 CTypes를 사용하고 있습니다. 이 라이브러리에 등록 된 콜백이 있는데, 라이브러리 자체에서 만드는 스레드의 컨텍스트에서 호출됩니다. 내 콜백 내에서 libc.malloc() (libc = cdll.LoadLibrary('libc.so.6'))을 호출하면 가짜 값을 반환한다는 것을 발견했습니다. 아니 NULL,하지만 내가 그것을 역 참조하는 경우 segfault를 일으킬 주소.c 스레드에서 ctypes를 통해 호출 할 때 Malloc이 실패합니다.

다른 사람이 내게 어떤 일이 일어날 지에 대한 통찰력을 주거나, 아니면 같은 방법으로 malloc()으로 전화를 걸 었는지 말해 줄 수 있습니까?

답변

1

ctypes가 정수가 아닌 포인터를 반환해야한다는 것을 알기 위해 malloc 호출을 제대로 anottating 하시겠습니까? (만약 당신이 64 비트 박스에서 작업한다면?)

0

아래 코드는 Windows에서 작동합니다. Linux에서도 비슷해야합니다. 적어도 32 비트 시스템에서는 명시적인 argtypes/restype 속성이 설정되지 않아도 작동합니다.

from ctypes import * 

crt = CDLL('msvcrt') 
malloc = crt.malloc 
malloc.argtypes = [c_size_t] 
malloc.restype = c_void_p 
free = crt.free 
free.argtypes = [c_void_p] 
free.restype = None 

n = cast(malloc(10),POINTER(c_ubyte)) 
for i in range(10): 
    print '{:02X}'.format(n[i]), 
free(n) 

콜백에 대해 언급 했으므로 사용 기간 동안 콜백에 대한 참조를 유지해야합니다. 즉 다음과 같이 호출하지 마십시오 :

set_callback(CFUNCTYPE(...)(callback_func)) 

콜백 설정 직후에 CFUNCTYPE 객체가 삭제됩니다. 대신 수행

@CFUNCTYPE(...) 
def callback_func(...) 
    ... 

set_callback(callback_func) 

이 장식 양식 (방법 경우, 또는 클래스)에 모듈의 삶의하는 ctypes 콜백 객체와 파이썬 함수 객체를 대체합니다.

관련 문제