3

私はこの質問を見つけましたが、1 つの答えは基本的に、それをしたくないというものでした: Swig を使用して C++ コードの C# ラッパーを構築するときに、既存のメソッドにコードを追加することは可能ですか?

OPが壊れやすい方法でコードを挿入しようとしていた場合、私は実際にそれに同意します。私の場合、答えが示唆したことを正確に行っています。メソッドの名前を変更し、 %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();
}

public void baz() { baz_internal(); のみ ... } が生成されます。ここでの問題は、スコープが CLASS::METHOD であるため、%rename と %typemap(javamethodmodifiers) は一意ですが、%typemap(javacode) はクラス全体に適用されることです。次のような構文の場合

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

がサポートされていれば、これで問題は解決します。これを達成できるテクニックはありますか?これは、デフォルトが空である javacode や javaimports などの typemap には意味があります。

4

2 に答える 2

1

お探しのコードを生成する SWIG マクロを作成できます。ちょっと面倒ですが、うまくいきます。トリックは、javacode の代わりに javaout (noblock=1) タイプマップを悪用して、クラスごとではなく関数ごとに 1 回適用されるようにすることでした。

%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タイプマップをコピーして別のアプローチを試みましたが、これは最終的にうまくいきませんでした。

何かを返すメソッドもサポートしたい場合は、3 番目のマクロ引数を追加する必要があります。

%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非プリミティブ/特殊なケースのリターンのために多くのコードを複製する必要がないように、デフォルトのあまり特殊化されていないタイプマップを参照するために使用されます。

于 2012-08-24T08:07:48.130 に答える