2012-08-24 1 views
2

나는이 질문을 찾았지만 하나의 대답은 당신이 그렇게하고 싶지 않아요, 기본적으로했다 : 나는 실제로 영업 이익은 방식으로 코드를 삽입하려고했던 바와 같이 경우에 동의 Is it possible to add code to an existing method when using Swig to build a C# wrapper for C++ code?swig에서 기존의 typemap에 "text"를 추가 할 수 있습니까?

을 깨지기 쉽다. 필자의 경우에는 대답의 제안과 정확히 일치하는 방법을 사용하고 있습니다. 메서드의 이름을 바꾸고 % typemap (javacode)을 사용하여 래핑 메서드를 구현합니다.

하지만 매크로로 작성 했으므로 몇 가지 메서드를 재정의하여 % typecode (javacode)를 여러 번 호출하고 javacode typemap의 마지막 래핑 메서드 만 활성화됩니다.

매크로의 세부 사항은 변수 args를 사용하여 서명을 표현하기 때문에 복잡합니다.

그러나 문제 시연 :

%define WRAP(CLASS,METHOD) 
%rename(method ## _internal,fullname=1) CLASS::METHOD; 
%typemap(javamethodmodifiers) CLASS::METHOD "private"; 
%typemap(javacode) { 
    public void METHOD() { 
     METHOD ## _internal(); // delegate to original 
     // extra code here 
    } 
} // (note: dont use %{ %} -- need macro evaluation) 
%enddef 

WRAP(Foo,bar) 
WRAP(Foo,baz) 

class Foo { 
    void bar(); 
    void baz(); 
} 

을 만 공개 무효 바즈() {baz_internal(); ...}가 생성됩니다. 여기서 문제는 % rename과 % typemap (javamethodmodifiers)가 CLASS :: METHOD에 대한 스코프 이후 유일하지만 % typemap (javacode)가 전체 클래스에 적용된다는 것이다.

%typemap(javacode,append=true) { // code } 

과 같은 구문이 지원되면 문제가 해결됩니다. 이것을 달성 할 수있는 방법이 있습니까? javacode 또는 javaimports와 같은 typemaps에는 기본값이 비어있는 경우이 값을 사용할 수 있습니다.

답변

1

찾고있는 코드를 생성하는 SWIG 매크로를 만들 수 있습니다. 그것은 교묘 한 비트지만, 작동합니다. 트릭은 오히려 한 번 클래스 당보다 기능에 한 번 적용됩니다 있도록 javacode 대신 타입 맵 (NOBLOCK = 1)을 javaout을 남용했다 :

%module test 

%define WRAP(CLASS,METHOD) 
%rename(METHOD ## _internal,fullname=1) CLASS::METHOD; 
%javamethodmodifiers CLASS::METHOD "private"; 
%typemap(javaout,noblock=1) void CLASS::METHOD { 
    { 
    $jnicall; 
    } 

    public void METHOD() { 
    METHOD ## _internal(); 
    // some other bits 
    } 
} 
%enddef 

WRAP(Foo,bar) 
WRAP(Foo,baz) 

class Foo { 
public: 
    void bar(); 
    void baz(); 
}; 

를이 정확하게 당신이 찾고있는 코드를 생성하지만 %rename을 건너 뛰고 javaout typemap에서이 모든 작업을 수행 할 수 있다고 의심해보십시오. 이 접근법은 SWIG 1.3 이상에서 작동합니다.

나는 $typemap으로 다른 접근법을 시도하고 주위에 typemap을 복사했지만, 결국에는 해결되지 않았습니다.

당신이 일을 반환 방법을 지원하려면 당신도 제 3 매크로 인수를 추가 할 수 있습니다 : 중복되는 것을 피하기 위해 기본에 덜 전문적인 typemap을 참조가 사용됩니다

%define WRAP(CLASS,METHOD,RETURN) 
%rename(METHOD ## _internal,fullname=1) CLASS::METHOD; 
%javamethodmodifiers CLASS::METHOD "private"; 
%typemap(javaout,noblock=1) RETURN CLASS::METHOD { 
    $typemap(javaout,RETURN) 

    public $typemap(jstype,RETURN) METHOD() { 
    RETURN result = METHOD ## _internal(); 
    // some other bits 
    return result; 
    } 
} 
%enddef 

$typemap 비 프리미티브/특수 사례를 반환하는 코드가 많이 있습니다.

+0

첫 번째 솔루션에 문제가 있습니다. 위임하는 메소드가 ** 내부 메소드 **에서 생성됩니다. % {%} (으)로 전환하고 추가}를 추가하면 고칠 수 있습니다. 매크로를 호출해야하기 때문에 이것이 문제가 될 수도 있습니다. 더 많은 것을 가지고 놀아 보겠습니다. % {%} 대 {}의 차이가 typemaps에 무엇인지 정확히 이해하는지 확신 할 수 없습니다. @Marvin – Marvin

+0

- 2.0과 1.3 모두에서 테스트했을 때 제대로 작동했습니다. 당신이 사용한 SWIG의 버전을 확인할 수 있습니까? typemap에'noblock = 1'을 (를) 확실히 했습니까? 'noblock = 1'을 생략하면 _internal 메소드 내부에서 생성 된 것을 볼 수 있습니다. 그렇지 않으면 괜찮습니다. (http://pastebin.com/d5tmdanY는 SWIG2.0과 첫 번째 스타일에서 얻은 것입니다.) – Flexo

+0

Swig 버전 2.0.5,하지만 ... – Marvin

관련 문제