C로 작성된 함수를 파이썬에서 사용하기

표준 파이썬 해석기는 C로 만들어져 있다. 그리고 C에는 동적 라이브러리를 링크하여 사용할 수 있는 기능이 마련되어 있다. 따라서 표준 파이썬 해석기를 만드는 사람들도 실행시간에 C로 만들어진 동적 라이브러리를 링크하여 사용할 수 있을 것이라는 생각을 당연히 했을 것이고, 그 결과 ctypes 라는 라이브러리가 탑재되어 있다. 

ctypes는 DLL이나 공유라이브러리 내의 함수를 로드해서 사용할 수 있도록 C 타입 및 함수를 파이썬으로 래핑할 수 있게 해주는 라이브러리이다. 

일례로 윈도의 표준 C 라이브러리는 MS Visual C Runtime DLL (그 유명한 msvcrt.dll)인데, 여기에 등재된 C 함수를 호출하여 사용하는 방법은 다음과 같다. 

from ctypes import windll
libc = windll.kernel32
libc.printf(b'hello world!\n')

먼저 C로 소수 판정함수를 수행하는 함수가 있는 파일을 하나 작성해보자.

// p.c
#include <math.h>

#define true (1)
#define false (0)

typedef int bool

bool isprime(int n)
{
  if (n < 2) return false;
  if (n == 2 || n == 3) return true;
  if (n % 2 == 0 || n % 3 == 0) return false;
  if (n < 9) return false
  int k = 5;
  int l = (int)(sqrt((double)n) + 0.5);
  while (k <= l) {
    if (n % k == 0 || n % (k + 2) == 0) return false;
    k += 6;
  }
  return true;
}

이 파일을 공유라이브러리로 컴파일한다. 컴파일 방법은 joinc의 내용을 참고한다. 

> gcc -fPIC -c p.c
> gcc --shared -op.dll p.o

이렇게하면 “p.dll” 이라는 이름의 공유라이브러리가 만들어진다. 이제 이 라이브러리 내의 isprime 함수가 파이썬에서도 동작할 수 있는지 확인해보자. 

# python 3.6.5
from ctypes import cdll
p = cdll.LoadLibrary('p.dll')
# p.dll 파일은 현재 디렉토리 위치에 있거나, PATH상에 있어야 한다.

print(sum(x for x in range(100_0000) if p.isprime(x)))

제대로 동작한다. 당연히 파이썬으로 동일한 알고리듬을 구현한 코드보다는 훨씬 빠르게 동작하는 것도 확인된다.