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

[SWIG강좌] 3.4 Typemap (2)

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



가입:
올린 글: 56

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

3.4.3. typemap 상세

(1) typemap 정의하기
typemap은 %typemap 명령으로 정의하는 데, %typemap 명령은 다음과 같다(parts enclosed in [ ... ] are optional).

%typemap(method [, modifiers]) typelist code;

method는 "in", "out", "argout"과 같이 typemap의 종류를 나타낸다. modifiers 는 name="value", name="value", ... 와 같이 쉼표로 분리된 리스트 형이이고, 부가 정보를 담고 있다. typelist는 typemap을 적용할 C++ type pattarn의 리스트로 다음과 같은 형태이다.

typelist : typepattern [, typepattern, typepattern, ... ] ;

typepattern : type [ (parms) ]
| type name [ (parms) ]
| ( typelist ) [ (parms) ]

각 type pattern 은 데이터형이 될 수도 있고, 데이터형과 인자명이 함께 할 수도 있다. 또한, 임시변수(parms)의 리스트를 포함 수도 있다.
code는 typempa에서 사용되는 C 코드를 의미하는 데 다음과 같은 형태이다.

code : { ... }
| " ... "
| %{ ... %}

다음은 typemap 선언의 예이다.

/* Simple typemap declarations */
%typemap(in) int {
$1 = PyInt_AsLong($input);
}
%typemap(in) int "$1 = PyInt_AsLong($input);";
%typemap(in) int %{
$1 = PyInt_AsLong($input);
%}

/* Typemap with extra argument name */
%typemap(in) int nonnegative {
...
}

/* Multiple types in one typemap */
%typemap(in) int, short, long {
$1 = SvIV($input);
}

/* Typemap with modifiers */
%typemap(in,doc="integer") int "$1 = gh_scm2int($input);";

/* Typemap applied to patterns of multiple arguments */
%typemap(in) (char *str, int len),
(char *buffer, int size)
{
$1 = PyString_AsString($input);
$2 = PyString_Size($input);
}

/* Typemap with extra pattern parameters */
%typemap(in, numinputs=0) int *output (int temp),
long *output (long temp)
{
$1 = &temp;
}

(2) Typemap scope
typemap은 한번 정의되고 나면, 따라오는 모든 선언문에 영향을 미치게된다. 만약 새로이 정의한다면, 그 이후는 새로 정의된 typemap이 적용된다. 예를 들어, 다음과 같다.

// typemap1
%typemap(in) int {
...
}

int fact(int); // typemap1
int gcd(int x, int y); // typemap1

// typemap2
%typemap(in) int {
...
}

int isprime(int); // typemap2

typemap scoping rules의 단하나의 예외는 %extend 명령과 연관이 있다. %extend는 클래스나 구조체의 정의에서 새로운 선언을 추가하는 데 사용되기 때문에, 클래스 자체가 정의될 때 유효한 typemap이 %extend 블록내의 선언에 유효하게 된다. 예를 들어 다음과 같다.

class Foo {
...
};

%typemap(in) int {
...
}

%extend Foo {
int blah(int x); // typemap has no effect. Declaration is attached to Foo which
// appears before the %typemap declaration.
};

(3) Copying a typemap
typemap의 복사는 =를 이용하거나, %apply 명령을 이용한다. 예를 들어 int 에 대한 typemap을 Integer로 복사하려면 다음과 같다.

%typemap(in) Integer = int;
또는
%apply int {Integer};

다음은 int typemap을 Integer, Number, int32_t로 복사한 경우이다.

%typemap(in) Integer, Number, int32_t = int;
%apply int {Integer, Number, int32_t};

%apply는 하나이상의 하나의 데이터형에 여러 typemap이 지정되어 있는 경우 모든 typemap을 복사한다, 즉,

%typemap(in) int { ... }
%typemap(out) int { ... }
%typemap(varin) int { ... }
%typemap(varout) int { ... }

%apply int { Integer }; // Copy all int typemaps to Integer
%apply int { Integer, Number }; // Copy all int typemaps to both Integer and Number

%apply에서의 패턴은 %typemap에서 사용하는 것과 같다. 즉,

%apply int *output { Integer *output }; // Typemap with name
%apply (char *buf, int len) { (char *buffer, int size) }; // Multiple arguments

(4) Deleting a typemap
typemap은 아무 코드가 없는 것을 정의하여 삭제하거나, %clear 명령을 사용한다. %clear 명령은 주어진 데이터형과 관련된 모든 typemap을 삭제한다. 예를 들어,

%typemap(in) int; // Clears typemap for int
%typemap(in) int, long, short; // Clears typemap for int, long, short
%typemap(in) int *output;

%clear int; // Removes all types for int
%clear int *output, long *output;

(5) Basic matching rules
Typemap을 정의할 때 주어진 형(TYPE)과 인자명(NAME)의 쌍으로 자신이 적용될 함수를 찾아낸다. 여기에는 다음과 같은 규칙이 있다.

- Typemaps that exactly match TYPE and NAME.
- Typemaps that exactly match TYPE only.

TYPE이 const, volatile 등과 같은 qualifier를 가질 경우 qualifier는 제외하고 찾는다:

- Typemaps that match the stripped TYPE and NAME.
- Typemaps that match the stripped TYPE only.

TYPE이 배열이면,

- Replace all dimensions to [ANY] and look for a generic array typemap.

예를 들어

int foo(const char *s);

에서 SWIG는 다음과 같은 순서로 적용할 typemap을 찾는다.

const char *s Exact type and name match
const char * Exact type match
char *s Type and name match (stripped qualifiers)
char * Type match (stripped qualifiers)

하나이상의 typemap이 정의되어 있다면, 처음으로 찾은 typemap을 적용한다.

%typemap(in) int *x {
... typemap 1
}

%typemap(in) int * {
... typemap 2
}

%typemap(in) const int *z {
... typemap 3
}

%typemap(in) int [4] {
... typemap 4
}

%typemap(in) int [ANY] {
... typemap 5
}

void A(int *x); // int *x rule (typemap 1)
void B(int *y); // int * rule (typemap 2)
void C(const int *x); // int *x rule (typemap 1)
void D(const int *z); // int * rule (typemap 3)
void E(int x[4]); // int [4] rule (typemap 4)
void F(int x[1000]); // int [ANY] rule (typemap 5)

(6) Typedef reductions
앞서의 설명에서 적절한 typemap을 찾지 못한다면, SWIG는 typedef문을 이용해 적절한 typemap을 찾는다.

%typemap(in) int {
... typemap 1
}

typedef int Integer;
void blah(Integer x);

Integer x에 대한 typemap을 찾기위해 SWIG는 먼저 다음과 같은 typemap을 찾는다.

Integer x
Integer

찾을 수 없다면, typedef 문을을 이용해 다음과 같은 typemap을 찾는다.

int x
int --> match: typemap 1

(7) Multi-arguments typemaps
multi-argument typemap은 single type에 대한 typemap보다 우선순위를 갖는다.

%typemap(in) (char *buffer, int len) {
// typemap 1
}

%typemap(in) char *buffer {
// typemap 2
}

void foo(char *buffer, int len, int count); // (char *buffer, int len)
void bar(char *buffer, int blah); // char *buffer

현재 버전의 SWIG에서는 multi-argument typemap에서 첫 번째 인자는 type만 기술할 수 있지만, 나머지 인자는 type, name pair를 정확하게 기술해야 한다. 예를 들어

%typemap(in) (char *, int len){..} // ok
%typemap(in) (char *, int){..} // error

(8)typemap method와 special variables
앞서에서 설명한 “in" typemap, "out" typemap 등을 typemap 메쏘드라고 한다. typemap 메쏘드에는 이외에도 상황에 따라 "typecheck" typemap, "arginit" typemap, "default" typemap, "check" typemap, "argout" typemap, "freearg" typemap, "newfree" typemap, "memberin" typemap, "varin" typemap, "varout" typemap 등이 있다. 여기에서는 다음의 4개의 typemap에 대해 설명할 것이다.

"in" typemap 은 Python에서 C로 함수의 인자를 변환할 때 사용된다.
"out" typemap 은 C의 함수/메쏘드 리턴 값을 Python으로 변환한다.
"argout" typemap은 인자로 값을 리턴할 때 사용된다.
"freearg" typemap은 인자 데이터를 cleanup하는 데 사용된다.

위에서 “freearg" ypemap은 어떤 인자가 메모리를 할당했고, wrapper 함수를 떠나기 전에 삭제해야 하는 경우에만 사용된다. "freearg" typemap 은 보통 “in" typemap에서 할당된 인자 리소스를 제거하는 데 사용된다. "freearg" typemap은 Python으로 제어가 반환되기 직전의, wrapper function에 끝에 삽입될 것이다. 이 코드는 또한 Wrapper function이 중간에 중단될 때마다 다른 typemap에서 사용될 수 있는 특수 변수 $cleanup 속으로 들어간다.
typemap을 정의할 때 $로 시작하는 특수변수가 있다. 이 특수 변수들은 C 코드를 생성할 때 특정한 변수로 변환된다. 이중에서 주로 사용하는 특수변수는 다음과 같다.

$result - Result object returned to target language.
$input - The original input object passed.
$n - A C local variable corresponding to type n in the typemap pattern.

위에서 $n은 모든 typemap에서 사용할 수 있고, $result는 “out", "argout" typemap에서, $input은 ”in", "argout" typemap에서 사용할 수 있다.

(9) Some bug
SWIG type map을 적용할 때 주의해야 할 점이 있다. 그 것은 overloading 된 함수에서 적용하면 안된다는 것이다. 예를 들어

void add(int a, int b, int* OUTPUT)
void add(int a, int b, int c, int* OUTPUT)

과 적용하면 add 함수를 제대로 호출하지 못한다.
위로
사용자 정보 보기 비밀 메시지 보내기    
이전 글 표시:   
글 쓰기   답변 달기    파이썬 마을 게시판 인덱스 -> 파이썬 팁/강좌/모듈소개 모음 시간대: GMT + 9 시간(한국)
페이지 11

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



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