2012-02-03 6 views
5

리눅스에서 네이티브 라이브러리에 래퍼를 쓰려고합니다. C에서파이썬 ctypes 네이티브 라이브러리 매개 변수로 구조체에 대한 포인터를 보내고

정의 : 파이썬

int mymethod(mystruct* ptr)

:

_lib.mymethod.argtypes = (ctypes.POINTER(mystruct),)
_lib.mymethod.restype = ctypes.c_int

s = mystruct()

_lib.mymethod(ctypes.byref(s))
레이즈 문제점이있다 : 대신 LP_mystruct

오류의

_lib.mymethod(ctypes.pointer(s))
이 예상 던질 수 LP_mystruct 인스턴스를 MYSTRUCT 대신 포인터의 예를 LP_mystruct 예상했다. 네이티브 메소드에 대한 포인터로서 구조체를 전달하는 방법은 무엇입니까?

감사합니다.

답변

5

문제는 그 상위 레벨 "POINTER"하는 ctypes로부터, 반품 단수 메모리를 나타내는이며 파이썬 "일반 포인터"(ctypes.byref 의해 ctypes.CArgObject) 이외의 다른 개체 당신이 `ctypes.c_voidp를 받고 대신 _lib.mymethod(ctypes.addressof(a))로 전화를 함수에 주석을 달 수 있습니다 - - (CTYPE의 adrresof에 의해 반환되는 것입니다) 주소

당신이 오류를 방지하기 위해 stronged 형식의 측면에서 작업 할 경우 또는 것 crash Python (형식 오류는 Python 예외를 발생시킵니다 - 잘못된 매개 변수가 C uncti에 전달됨 on은 파이썬 인터프리터 자체에서 세그멘테이션 오류를 일으킨다.) 구조체의 POINTER 인 새로운 "type"을 보유 할 변수를 생성 한 다음 구조체의 주소를 사용하여이 유형의 인스턴스를 생성해야한다.

mystruct_pointer = ctypes.POINTER(mystruct) 
_lib.mymethod.argtypes = (mystruct_pointer,) 
_lib.mymethod.restype = ctypes.c_int 

s = mystruct() 

_lib.mymethod(mystruct_pointer.from_address(ctypes.addressof(s))) 
+1

감사합니다. 내가 말한 두 번째 방법을 사용했는데 문제없이 작동합니다. – mete

+0

여기에 비슷한 - https://codexample.org/questions/238108/python-ctypes-sending-pointer-to-structure-as-parameter-to-native-library.c –

+0

ctypes에서 상위 수준의 POINTER 유형은 어느 것입니까 ? –

3

(나는이 오래된 질문이다 알지만, 내가 허용 대답은 불필요한 해결 방법이라고 생각, 그래서 후대를 위해 여기를 떠나고 싶어.)

이 실제로 통과 byref()을 사용해야 explicitly support을하는 ctypes 다음과 같은 포인터 :

ctypes는 매개 변수를 참조로 전달하는 데 사용되는 byref() 함수를 내 보냅니다. pointer() 함수를 사용하면 동일한 효과를 얻을 수 있지만 실제 포인터 객체를 생성 한 이후 pointer()이 더 많은 작업을 수행하므로 파이썬 자체에서 포인터 객체가 필요하지 않으면 byref()을 사용하는 것이 더 빠릅니다. argtypes 할당 한 정의를보고 함수 호출이 다른 사람을 보는 경우,이 혼란 오류가 발생 -

이것의 원인은 당신이 (예를 들어, 다른 모듈에서) 이상 한 곳에서 구조체를 정의한 것입니다. 즉, ctypes는 내용이 동일하고 (아마도) 동일한 두 개의 mystruct 유형을 일치 시키려고 시도하지만 정확히 동일한 이름을 갖지만 과 동일하게 유형이 아닙니다.기본 구조체 유형이 단일 유형 객체 인 경우 pointer(), byref() 또는 POINTER()()을 사용하여 포인터를 구성하면 상관 없습니다. ctypes는 기본 (지적 된) 유형이 동일 함을 감지합니다.

외부 함수를 호출하기 전에 바로 확인하려면 assert(_lib.mymethod.argtypes[0]._type_ == type(s))을 시도하십시오.

관련 문제