조용한 담장

tkinter와 cffi 간단한 툴 제작 본문

python

tkinter와 cffi 간단한 툴 제작

iosroid 2024. 4. 11. 19:20

UI? tkinter와 pyqt 중 아래의 이유로 tkinter 선택

  • UI 복잡도가 낮아서 문서만 보고 바로 사용 가능
    • 단순한 UI 요소들을 그리드 구조로 위치만 잘 잡아주면 되서 편함
    • Pygubu라는 UI 제작 툴도 있음.
      • XML 파일로 UI 구조를 생성해 줌.
      • pygubu-designer로 직관적인 UI 구성 가능.
      • XML 구조가 코드로 뚝딱 뚝딱 만든 것보다 더 복잡하게 느껴져서 안 씀.
  • 추가 설치 필요 없음.
  • 라이센스 편함.

cffi로 c 코드 함수 사용.

  • 처리 속도에서 우월.
  • 처리 데이터의 양이 많을수록 확실한 차이가 남.
  • ctypes와 비교했고, 함수선언이 cffi 가 c 코드 그대로 사용해서 익숙해 보였음.
# cffi
my_int = ffi.new("int[1]")
my_int[0] = 5

# ctypes
my_int = ctypes.c_int(5)
my_int_ptr = ctypes.pointer(my_int)

 

C 함수 X() 선언.

이건 라이브러리의 헤더에 정의된 내용.

ffi.cdef("""
int x(
	uint8_t *buf,
	uint32_t *out_size,
	const uint8_t *data,
	uint32_t data_size,
	const uint8_t *p,
	uint32_t p_size,
	uint32_t t,
	uint32_t e,
	const uint8_t *u,
	uint32_t u_size
	);
""")

 

데이터를 넘겨받는 buf 에는 메모리 공간을 미리 할당.

out_buf = ffi.new("char[]", 512)

 

C의 배열 변수에 데이터를 넣듯이 파이썬 변수에도 값을 저장해 줘서 전달.

메모리 공간은 미리 할당.

파이썬 변수 dataBytes는 bytearray 타입.

data = ffi.new("uint8_t[]", len(dataBytes))
idx = 0
for d in dataBytes:
    data[idx] = d
    idx += 1

 

상수값이나 NULL 은 직접 값으로 전달 가능.

result = mylib.x(
        out_buf,
        out_size,
        data,
        len(dataBytes),
        ffi.NULL,
        0,
        0x1010,
        1,
        ffi.NULL,
        0
    )

 

C 함수의 리턴값이 result에 저장됨.

out_buf는 cffi의 타입(cdata)이므로 unpack을 이용해 데이터를 파이썬 변수로 저장해야 함.

outBufUnpack = ffi.unpack(out_buf, out_size[0])

 

out_size는 out_buf의 크기인데 uint32_t* 타입이라 [0]로 값을 읽어올 수 있음.

 

ffi.new로 생성한 변수는 ffi.release로 메모리 해제함.

설명에선 아래와 같다. 예상 가능한 시점의 빠른 해제를 위해 넣어줌.

The normal Python destructor of the cdata object releases the same resources, but this allows the releasing to occur at a known time, as opposed as at an unspecified point in the future.

 

 

Comments