문제

C 함수 myfunc 더 큰 데이터 덩어리에서 작동합니다. 결과는 청크로 콜백 함수로 반환됩니다.

int myfunc(const char *data, int (*callback)(char *result, void *userdata), void *userdata);

사용 ctypes, 전화하는 것은 큰 문제가 아닙니다 myfunc Python Code에서 결과를 Python 콜백 함수로 반환합니다. 이 콜백은 잘 작동합니다.

myfunc = mylib.myfunc
myfunc.restype = c_int
myfuncFUNCTYPE = CFUNCTYPE(STRING, c_void_p)
myfunc.argtypes = [POINTER(c_char), callbackFUNCTYPE, c_void_p]

def mycb(result, userdata):
    print result
    return True

input="A large chunk of data."
myfunc(input, myfuncFUNCTYPE(mycb), 0)

그러나 콜백 함수에 대한 userData로 Python 객체 (예 : 목록)를 제공하는 방법이 있습니까? 결과 청크를 저장하려면 예를 들어 다음을 수행하고 싶습니다.

def mycb(result, userdata):
    userdata.append(result)

userdata=[]

그러나 Python 목록을 C_Void_P에 캐스팅하는 방법을 모르겠습니다.

현재의 해결 방법은 링크 된 목록을 CTypes 구조로 구현하는 것입니다.

도움이 되었습니까?

해결책

나는 당신이 사용할 수 있다고 생각합니다 파이썬 C API 그렇게하려면 ... 아마도 당신은 pyobject 포인터를 사용할 수 있습니다.

편집하다: OP가 의견에서 지적했듯이 이미 py_object CTYPES로 쉽게 사용할 수 있으므로 솔루션은 먼저 ctypes.py_object 파이썬 목록에서 객체를 한 다음 주조 c_void_p C 함수에 대한 인수로 전달하려면 void* 포인터를 받아 들여야하며 전달하는 것이 더 빠릅니다. byref). 콜백에서 리버스 단계가 수행됩니다 (공간 포인터에서 포인터로 캐스팅 py_object 그런 다음 내용의 가치를 얻습니다).

해결 방법은 콜백 함수에 클로저를 사용하는 것이므로 이미 항목을 추가 해야하는 목록을 이미 알고 있습니다 ...

myfunc = mylib.myfunc
myfunc.restype = c_int
myfuncFUNCTYPE = CFUNCTYPE(STRING)
myfunc.argtypes = [POINTER(c_char), callbackFUNCTYPE]


def mycb(result, userdata):
    userdata.append(result)

input="A large chunk of data."
userdata = []
myfunc(input, myfuncFUNCTYPE(lambda x: mycb(x, userdata)))
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top