ctypes를 통해 c++ array를 python list로 변환하기

2020. 3. 1. 04:22Develop

 

float* makeArray(){
    float *arr = malloc(2 * sizeof(double));
    A[0] = 0.123;
    A[1] = 0.456;
    return arr;
}

 

위와 같이 C 레벨에서 malloc을 통해서 메모리 공간에 할당 된 배열이 있을 때 이를 파이썬 리스트로 변환하려면 ctypes 라이브러리를 활용하면 된다. 파이썬 레벨로 올라가기 전에 C 레벨에서 미리 memory free를 위한 함수를 정의해준다.

 

void freeptr(void *ptr)
{
    free(ptr);
}

 

만약에 위와 같은 함수들이 포함된 소스를 shared objective file로 컴파일 했다면 다음과 같이 사용할 수 있다. (만약 Cython을 사용하면 굳이 .so 파일을 만들 필요가 없다.)

 

import ctypes
lib_cpp = ctypes.CDLL('./test.so')

# C에서 정의한 makeArray 함수는 2개의 float을 가리키는 포인터를 리턴한다.
lib_cpp.makeArray.restype = ctypes.POINTER(ctypes.c_float * 2)

# freeptr 함수는 void pointer 한개를 인자로 받는다.
lib_cpp.freeptr.argtype = ctypes.c_void_p
# freeptr 함수는 return 값이 없다. (return void)
lib_cpp.freeptr.restype = None

# makeArray 함수를 호출하여 float array pointer를 얻는다.
darrayptr = lib_cpp.Make_A()
# array pointer가 가리키는 데이터 contents를 Python list로 변환한다.
floatlist = [x for x in darrayptr.contents]

# C 레벨에서 malloc 되었으므로 C 레벨에서 정의된 free 함수를 통해서 메모리 해제를 해준다.
lib_cpp.freeptr(darrayptr)