파이썬 마을 게시판 인덱스 파이썬 마을
우리나라 파이썬 사용자들의 이야기 마을
 
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 
Google
python.or.kr Web

[SWIG강좌] 3.4 Typemap (1)

 
글 쓰기   답변 달기    파이썬 마을 게시판 인덱스 -> 파이썬 팁/강좌/모듈소개 모음
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
jrcho



가입:
올린 글: 56

올리기올려짐: 2004 5월 12 7:26 pm    주제: [SWIG강좌] 3.4 Typemap (1) 인용과 함께 답변

3.4. Typemap

3.4.1. Why typemap ?

실제로 C/C++ 코드를 Python에서 사용하도록 SWIG를 사용할 경우 형 변환과 관련된 문제에 부딪치게 된다. 예를 들어 다음의 함수를 보길 바란다.

void add(int a, int b, int *result); // result는 출력

add() 함수는 result 인자에 결과값을 받아 온다. 하지만 SWIG는 result의 형이 int *이므로 포인터로 취급하게 된다. 따라서 Python에서

>>> add(1,2,result)

와 같은 호출은 형검사 과정에 오류가 있게 된다. 또한 Python은 함수의 결과값을 함수의 좌측에서 지정한다. 따라서 wrapper를 생성할 때

>>> c = add(1,2);

와 같이 쓸 수 있도록 해야 한다. 이를 위해서는 typemap이라는 것을 이용해야 한다. 위와 같이 Python 인터프리터에서 사용하기 위해서는 wrapper 코드가 다음과 같이 되어야 할 것이고, typemap을 사용하면 만들 수 있다.

static PyObject *_wrap_add(PyObject *self, PyObject *args) {
PyObject *resultobj;
int arg1, arg2 ;
int *arg3;

if(!PyArg_ParseTuple(args,(char *)"ii:add",&arg1,&arg2)) goto fail;
add(arg1,arg2,arg3);

return PyInt_FromLong((long) (*arg3));
}

Typemap의 정확한 정의는 특정 C 데이터 형에 적용되는 코드 생성 규칙으로 사용분야는

- 입출력 변수를 다루거나

- Python 객체를 대응되는 C/C++ 변수로 바꾸거나(tuples,lists, 등)

- SWIG에게 새로운 Python type을 알리거나

-constraint handling추가할 때 사용된다.(the constraint library is really just typemaps).

등이다. Typemap은 매우 방대한 내용이기 때문에 여기서 기본 원리 및 실제 필요한 내용에 대해서만 다루기로 하겠다. SWIG는 C/C++ built-in type에 대한 기본적인 typemap을 담고 있는 표준라이브러리 typemaps.i가 있고, 그 외의 것은 사용자가 직접 작성해야 한다.

3.4.2. typemap basic

typemap은 %typemap 명령으로 SWIG에서 작성한다. 간단한 예로,

%typemap(in) int { ... code ... }
%typemap(out) int { ... code ... }

등이 있다. in, out 은 typemap의 종류를 나타내는 것으로, %typemap(in)은 "in" typemap으로 Python에서 C로 값을 변화시키는 데 사용되는 typemap을 의미하면, %typemap(out)은 "out" typemap으로 Python에서 C로 값을 변화시키는 typemap을 정의한 다는 것이다. %typemap(in), %typemap(out) 다음에는 typemap을 적용할 C 데이터 형(위에서는 int)과 변환하는 코드({...}의 부분)가 따라오게 된다.
다음 예를 보길 바란다. fact1() 함수는 typemap을 적용하지 않는 경우이고, fact2()는 typemap을 적용한 경우이다. fact1() 함수는 typemap을 적용하지 않고 wrapper를 만들고, fact2()는 두개의 typemap을 적용한다. %typemap은 자신이 선언된 이후부터 적용되다. 따라서 fact1()에는 영향을 주지않고, fact2()의 wrapper를 생성할 때만 영향을 준다.

코드:

%module example

int fact1(int n);

%typemap(in) int {
// "in" typemap start
$1 = PyInt_AsLong($input);
// "in" typemap end
}

%typemap(out) int {
// "out" typemap start
$result = PyInt_FromLong($1);
// "out" typemap start
}

int fact2(int n);


SWIG를 실행하여 생성된 파일을 살펴보면 다음과 같은 wrapper 함수가 생성되었음을 확인할 수 있다.


코드:

static PyObject *_wrap_fact1(PyObject *self, PyObject *args) {
    PyObject *resultobj;
    int arg1 ;
    int result;
   
    if(!PyArg_ParseTuple(args,(char *)"i:fact1",&arg1)) goto fail;
    result = (int)fact1(arg1);
   
    resultobj = PyInt_FromLong((long)result);
    return resultobj;
    fail:
    return NULL;
}

static PyObject *_wrap_fact2(PyObject *self, PyObject *args) {
    PyObject *resultobj;
    int arg1 ;
    int result;
    PyObject * obj0 = 0 ;
   
    if(!PyArg_ParseTuple(args,(char *)"O:fact2",&obj0)) goto fail;
    {
        // "in" typemap start
        arg1 = PyInt_AsLong(obj0);
        // "in" typemap end
    }
    result = (int)fact2(arg1);
   
    {
        // "out" typemap start
        resultobj = PyInt_FromLong(result);
        // "out" typemap start
    }
    return resultobj;
    fail:
    return NULL;
}


위에서 두 함수

long PyInt_AsLong(PyObject *obj); // Python --> C
PyObject *PyInt_FromLong(long x); // C --> Python

는 형변환과 관련된 Python/C API 함수이다. 위에서 typemap으로 작성된 코드는 이 {} 기호 안에서 복사되어 들어간다. 이를 이용해 필요한 형변환을 수행할 수 있다. 각 typemap은 작은 C 코드를 담고 있고, SWIG가 생성하는 wrapper fucntion에 삽입되게 된다. typemap을 정의할 때 $기호로 쓴 변수들은 실제 wrapper를 생성할 때 정해진 규약에 의해 바뀌게 된다. $input은 C로 변환도어야 할 객체를 가르키고, $result 는 wrapper 함수에 의해 리턴되는 객체를 가르킨다. $1 은 typemap 선언에 지정된 것과 동일한 형을 가지는 C 변수(여기서는 int 형을 갖는 변수)를 가르킨다. 이러한 방식으로 typemap은 생성되는 wrapper function에 일정한 규칙을 갖는 코드를 삽입할 수 있도록 해준다.
예에서 알 수 있듯이 typemap은 C wrapper함수를 생성할 때 사용자가 지정한 규칙대로 생성하도록하는 기능을 함을 알 수 있다. 여기에서는 "in" typemap과 "out" typemap을 이용하여 그 원리를 설명하였다. SWIG에서 정의한 typemap에는 상황에따라 사용할 수 있는 typemap이 여러 가지가 있다. 예를 들어 "argout" typemap은 함수의 인자로 리턴값을 받아올때 사용한다.
위로
사용자 정보 보기 비밀 메시지 보내기    
이전 글 표시:   
글 쓰기   답변 달기    파이썬 마을 게시판 인덱스 -> 파이썬 팁/강좌/모듈소개 모음 시간대: GMT + 9 시간(한국)
페이지 11

 
건너뛰기:  
새로운 주제를 올릴 수 없습니다
답글을 올릴 수 없습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다



Powered by phpBB © 2001, 2005 phpBB Group
회선/장비: Daum DNA , 관리: 장혜식,서상현