Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

SWIG를 활용해 Python에서 C/C++ 코드 래핑하기

기존에 작성된 C 또는 C++ 기능을 Python에서 사용하도록 래핑하는 방법은 여러 가지가 있습니다. 이 글에서는 그중 SWIG(Simple Wrapper Interface Generator)를 이용해 C/C++ 기능을 Python으로 래핑하는 방법을 살펴보겠습니다.

C/C++을 Python으로 래핑하는 대표적인 방법

  • 수동 래핑(Manual wrapping)
  • Pyrex를 이용한 C 코드 래핑
  • Ctypes
  • SIP
  • Boost Python

SWIG는 C 코드를 Perl, Python, PHP, Ruby, Tcl, C#, Common Lisp(CLISP, Allegro, CL, UFFI, CFFI), Java, Modula-3, OCAML 등 다양한 언어로 래핑할 수 있는 강력한 도구입니다. 또한 Guile, MzScheme, Chicken 같은 여러 Scheme 구현체(인터프리터 및 컴파일 방식 모두)도 지원합니다.

이 글에서는 그중 Python과의 연동 방법만 다루겠습니다. SWIG는 본질적으로 일종의 매크로 언어로, C 코드를 해석한 뒤 원하는 언어에 맞는 래퍼(wrapper) 코드를 자동으로 생성해 줍니다.

SWIG 설치

여기서는 Windows용 설치 파일인 "swigwin-3.0.12"를 사용했습니다. 아래 공식 사이트에서 다운로드할 수 있습니다.

https://www.swig.org/download.html

또한 Windows 환경에서 SWIG 프로그램을 실행하려면 "Microsoft Visual Studio 14.0" 이상이 추가로 필요할 수 있습니다.

SWIG의 활용 예를 들어보겠습니다. 어떤 C 함수가 있고, 이를 Tcl, Perl, Python(여기서는 Python 사용), Java, C# 같은 다른 언어에서도 사용하고 싶다고 가정해 봅시다.

예제 C 파일 — example.c

#include "example.h"
int fact(int n) {
    if (n < 0) {      /* 원래는 오류를 반환하는 것이 좋지만, 여기서는 간단히 처리 */
        return 0;
    }
    if (n == 0) {
        return 1;
    } else {
      /* 오버플로 검사를 추가하는 것이 좋습니다 */
      return n * fact(n-1);
   }
}

인터페이스 파일

C 파일을 원하는 언어에 연결하려면 SWIG의 입력으로 사용되는 "인터페이스 파일"을 작성해야 합니다. example.c에 대한 인터페이스 파일은 다음과 같습니다.

example.i

/* File: example.i */
%module example
%{
    #define SWIG_FILE_WITH_INIT
    #include "example.h"
%}
%include "example.h"

헤더 파일

앞선 예제에서 헤더 파일을 포함시켰으므로, 헤더 파일 내용은 다음과 같습니다.

example.h

int fact(int n);

셋업(setup) 파일

from distutils.core import setup, Extension
example_module = Extension('_example',
    sources=['example_wrap.c', 'example.c'],
)
setup (name = 'example',
   version = '0.1',
   author = "SWIG Docs",
   description = """Simple swig example from docs""",
   ext_modules = [example_module],
   py_modules = ["example"],
)

래퍼 생성하기

이제 인터페이스 파일(example.i)을 사용해 Python 래퍼를 만들어 보겠습니다. 함수에 대한 래퍼를 생성하려면 명령줄(CLI)에서 아래 명령어를 실행하기만 하면 됩니다.

>swig -python example.i

명령을 실행하면 현재 작업 디렉터리에 새 파일이 생성됩니다. 위 예제와 동일한 파일명을 사용했다면 래퍼 파일은 "example_wrap.c"로 생성되며, 다른 이름을 사용했다면 다음 형식으로 이름이 지정됩니다.

"Your_File_Name" + "_wrapper" + "Your_language_extension"

예를 들어 예제 파일이 test.c라면 래퍼 파일은 "test_wrapper.c"가 됩니다.

확장 모듈 빌드하기

>python setup.py build_ext
running build_ext
building '_example' extension
creating build
creating build\temp.win32-3.6
creating build\temp.win32-3.6\Release
….

이것으로 C 언어로 작성된 기능을 Python에서 사용할 수 있게 되었습니다. 확인하려면 바로 실행하거나, 가상 환경(virtual environment)을 만들어 별도로 실행해 볼 수 있습니다.

C:\Users\rajesh>mkdir swigExample && cd swigExample
C:\Users\rajesh\swigExample>virtualenv swigenv
Using base prefix 'c:\\python\\python361'
New python executable in C:\Users\rajesh\swigExample\swigenv\Scripts\python.exe
Installing setuptools, pip, wheel...done.

C:\Users\rajesh\swigExample>.\swigenv\Scripts\activate

(swigenv) C:\Users\rajesh\swigExample>python

이제 완성되었습니다. 모듈에서 함수를 가져와 실행해 보세요.

>>> from example import fact
>>> fact(6)
720