로그인

검색

Python
2014.02.10 15:31

파이썬에서 C모듈 사용하기

MoA
조회 수 2550 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄
파이썬은 그 자체가 C로 작성되었다.
 
이런 맥락에서 생각해보면 파이썬에서 C모듈을 사용할수도 있을뿐 아니라 C에서 파이썬 모듈을 사용할수도 있을것 같다. -> 이말은 사실이다.
 
본론으로 들어가기전에 파일의 확장자에 대해 살포시 살펴보기로 하자.
 
파일의 확장자는 그 파일의 속성과 종류를 손쉽게 알려주는 역할을 한다. (이는 어떻게 보면 있어도 되고 없어도 되는 존재이며, 관습적으로 사용하게 된다.)
 
우리가 흔히 알고 있는 확장자로는 'exe', 'txt', 'jpg', 'mp3' 등 수없이 많다.
 
- lib : 정적 라이브러리 파일, 일반적으로 C, C++ 라이브러리다.
- dll : 동적 라이브러리 파일
- pyd : 파이썬이 사용하는 C 라이브러리
 
여기서는 C로 작성된 코드를 이용하여 pyd를 만들고 이 pyd를 이용해서 C 모듈을 이용하는 방법에 대해서 살펴본다.
 
1. 파이썬 코드에서 import를 하면 일어나는 일
 
파이썬에서 특정한 모듈을 사용하기 위해 import문을 이용하여 모듈을 지정한다. 파이썬이 사용하고 로드하는 모듈은 아래의 순서로 찾고 그와 일치하면 모듈을 초기화한 후에 지역 이름공간에 이름을 정의한다.
 
    - 기본적으로 탑재되어 있는 모듈들 : ex)socket, time 등
    - C로 만들어진 dll 파일(윈도에서는 pyd 파일)
    - 자체 제작한 파이썬 모듈
 
그러면 파이썬에서 import는 어떤 매커니즘으로 동작하는가? 이것을 함 알아보자.
 
import mylib
 
위의 코드를 수행할때 파이썬은 mylib 모듈을 로드하기 위해 다음의 절차에 따라 검색한다.
 
    1) sys.modules 에 등록되어 있는지 확인한다. 등록되어 있으면 로드한다.
    2) 1)에서 존재하지 않으면 sys.path의 디렉토리를 검색하면서 mylib 모듈을 찾는다.
 
다시 한번 요약하면, 외부 모듈을 import 하게되면 파이썬은
 
    1) 모듈이름과 일치하는 모듈을 찾는다.
    2) 모듈을 초기화 한다.
    3) 모듈이름을 지역이름공간에 할당한다.
 
2. 파이썬에서 이용할 C 모듈 만들기
 
여기서 우리는 우리가 만든 C 모듈을 파이썬에서 사용하고 싶다. 즉,
 
import (우리가 만든 C 모듈) 하고 싶다 이 말이다.
 
우리가 C로 만든 모듈을 파이썬에서 이용하고자 할때 역시 위에서 서술한 import 절차에 따라 모듈을 찾고 로드하게 된다.
 
우리가 유의해야 할 곳은 바로 모듈을 초기화 하는 부분이다. 나머지 절차는 파이썬이 다 알아서 해준다.
 
파이썬에서 사용하는 C모듈은 리눅스에서는 .so 확장자 형태로, 윈도에서는 .pyd 확장자 형태로 빌드되어 파이썬 패키지 디렉토리의 Lib/site-package 디렉로리로 복사되므로서 사용가능하게 된다.
 
    1) C로 소스코드를 작성한다.
    2) 작성한 C 소스코드를 컴파일하여 파이썬이 이용가능한 .so (리눅스에서) 및 .pyd(윈도용) 파일로 빌드한다.
    3) .so 및 .pyd 파일을 파이썬 디렉토리의 Lib/site-package로 복사한다.
 
그러면 하나의 실제 C모듈을 만들어 적용하므로서 설명해보자.
 
파이썬이 C 모듈을 import 하게되면 초기화를 위해 "init+모듈이름" 으로 된 함수를 호출한다. 모듈이름이 mylib 이면 initmylib()을 호출한다는 말이다.
 
그러므로 우리의 C 소스에는 위에서 설명한 초기화를 위한 함수 init+모듈이름 으로 된 함수가 존재해야만 한다.
 
예제로 만들 모듈은 입력한 문자열을 pylog.txt 라는 파일에 기록하는 모듈이다. 주석을 달았으므로 주석을 참조하도록 한다.
 
// mylib.c
#include "Python.h"
#include <stdio.h>
 
static PyObject *ErrorObject;

// 실제 동작하는 함수
static PyObject* write_log(PyObject *self, PyObject *args) // 인자는 이와같이 고정된다.
{
    char* msg;
    FILE *fp;
    
    if(!PyArg_ParseTuple(args, "s", &msg))
        return NULL;
    
    fp = fopen("c:\pylog.txt", "wt+");
    fprintf(fp, msg);
    fclose(fp);
    
    return Py_BuildValue("i", 0);    
}
 
/* methods 구조체 배열에 지정되는 정보는 {"실제사용할 메쏘드명", 메쏘드명에 대응하는 실제 동작하는 함수명, 인자 종류} */
static struct PyMethodDef methods[] =
{
    {"wlog", write_log, METH_VARARGS},
    {NULL, NULL}
};
 
//
void initmylib()
{
    PyObject* m;
   
   // Py_InitModule("모듈명", 이모듈에 적용된 메쏘드들을 담을 구조체배열 포인터)
    m = Py_InitModule("mylib", methods); 

    ErrorObject = Py_BuildValue("s", "error");
}
 
위의 C 코드를 컴파일하기 위해 setup.py 함수를 작성해야 한다.
 
# setup.py
from distutils.core import setup, Extension
 
setup(name = "mylib",
        version = "1.0",
        description = "print log",
        author = "Samsjang",
        author_email = "samsjang@cdnetworks.co.kr",
        url = "http://www.cdnetworks.co.kr",
        ext_modules = [Extension("mylib", ["mylib.c"])]
        )
 
위의 소스에서 ext_modules에는 적용할 모듈명과 그 모듈의 구현코드를 기록한다. 나머지 부분의 기타 정보를 기록해둔 메타정보에 불과하다.
 
리눅스 및 윈도에서 아래와 같이 빌드하고 설치한다.
 
python setup.py install
 
위의 명령은 리눅스에서는 gcc를 호출하며, 윈도에서는 visual C++ 컴파일러가 구동되면서 빌드한 후 파이썬 디렉토리의 Lib/site-packages 디렉토리에 mylib.so 또는 mylib.pyd  파일이 생성된다.
 
자 그럼 C모듈인 mylib 모듈을 실제 파이썬 코드에서 적용해보자.
 
# test.py
import mylib
 
if __name__ == '__main__':    
    mylib.wlog('I love U')

위의 결과는 C:\pylog.txt 파일에 "I love U" 라는 글을 남긴다.

http://blog.naver.com/ksb1023yjs?Redirect=Log&logNo=50005795949
?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 Tool/etc Programming 게시판 관련 2 MoA 2014.11.01 5344
108 API/MFC 비주얼 스튜디오 2005 단축키 MoA 2013.07.28 1532
107 API/MFC VC의 소스 파일, sln파일 관리 MoA 2013.07.28 1241
106 API/MFC 비베의 MSCOMM.OCX VC++에서 불러쓰기 MoA 2013.07.28 1596
105 API/MFC VC++6.0 에서 VC++ 2005로 변환할 경우 형변환 경고 대응방법 MoA 2013.07.28 1368
104 C/C++ ofstream ifstream MoA 2013.07.28 1389
103 API/MFC MFC기반의 CSocket 사용 방법과 예제 MoA 2013.07.28 2044
102 API/MFC Sleep() 함수 대신 프로그램 딜레이 시키기 (Wait) MoA 2013.07.28 5856
101 C/C++ C, C++ 에서의 불(bool, boolean) 타입의 동작 MoA 2013.07.28 1150
100 C/C++ Simplified Logger Class MoA 2013.07.28 1234
99 C/C++ Buffer Overrun MoA 2013.07.28 1364
98 C/C++ Google의 C++ 라이브러리 MoA 2013.07.28 1447
97 C/C++ fwrite(), fread() MoA 2013.07.28 1364
96 C/C++ Binary 데이터 저장 by Google MoA 2013.07.28 1173
95 API/MFC 후킹 링크 MoA 2013.07.28 1525
94 API/MFC 모달창 세팅값 저장 MoA 2013.07.28 799
93 API/MFC DoModal Dialog 기초 MoA 2013.07.28 864
92 C/C++ C 언어의 문자형 변수 char - 8비트 정수형 변수 MoA 2013.07.28 2840
91 C/C++ C언어의 변수 float와 double - Float Point 처리 MoA 2013.07.28 1024
90 Site 알고리즘 정리된 블로그 MoA 2013.07.28 719
89 C/C++ 비트연산자 MoA 2013.07.28 1180
Board Pagination Prev 1 ... 5 6 7 8 9 10 11 12 13 14 15 Next
/ 15