[t:/]$ 지식_

파이썬 ctypes 포인터

2022/11/08

고속 루틴만 C 코드로 빼두고 글루 레이어를 파이썬으로 쓰는 상황이다.

a = ctypes.POINTER(c_int)

a 는 c_int의 포인터 생성자가 된다. 아래의 결과는 모두 같다.

mm.aa = ctypes.pointer(ctypes.c_int(10))

c_int_p = ctypes.POINTER(ctypes.c_int)
mm.aa = c_int_p(ctypes.c_int(10))

mm.aa = ctypes.POINTER(ctypes.c_int)(ctypes.c_int(10))

c측으로 함수 인자로만 전달하려면 byref()를 쓰면 빠르다. 내부적으로 객체 만든다고 지지고 볶고 하는 과정을 다 생략하는 것 같다. 추정컨데 스택에 걍 주소만 넘기고 땡치는 듯.

내부에 포인터 멤버 변수가 있는 구조체를 만드려면,

c_int_p = ctypes.POINTER(ctypes.c_int)

class aa(ctypes.Structure):
    _fields_ = [ ("aa", c_int_p),
            ("bb", ctypes.c_int) ]

이 구조체를 포인터로 C 함수로 넘기려면 다음과 같이 byref만 쓰면 된다. C에서 구조체를 직빵으로 넘기는 아규먼트는 금기였고 (대량 스택 복사) 시도도 안 해봤지만 어느날 넘한테 받은 코드에서 구조체 아규먼트가 있는 것이 아닌가? 심지어 컴파일도 잘 되고 실행도 잘 됐따.. 하지만 나는 여전히 그런 방식은 쓰지 않는다. 구조체에 대형 배열을 넣고 스택 오버런이 나면서 어쩌고 저쩌고 나한테 머라머라 이하 생략.

t = ctypes.cdll.LoadLibrary('./mp.so')

t.get_aa(ctypes.byref(mm))

print (mm.aa.contents.value)
print (mm.bb)

contents까지 쓰면 c_int형으로 리턴이다. 아마도 c_int 객체 내부에 파이썬 객체가 있을 것이다. .value까지 쓰면 파이썬 객체로서의 int값이 되는데, 아마도 ctypes를 쓴다고 메타들이 붙어 있어서 그런 것 같다.

퀴즈 : 이 글에서 "아마도"는 몇 개 일까요?

이제 파보는 건 못하겠읍니다. 나이 먹었읍니다. 파를 보고 있으면 눈물이 납니다. 아마도는 아마가 유명한 섬인데 아마를 재배해서 집을 짓고 아마씨유로 튀김을 해먹는다고 합니다.









[t:/] is not "technology - root". dawnsea, rss