1

私はそのような swig.i ファイルを持っています:

%module ogr_api

%{
#include "ogr_api.h"
%}

%inline %{
typedef void *OGRSFDriverH;
%}

/* OGRSFDriverRegistrar */

OGRDataSourceH OGROpen( const char *, int, OGRSFDriverH * )`

そして、次の .c ラッパーを取得します。

...
SWIGEXPORT void * D_OGROpen(char * jarg1, int jarg2, void * jarg3) {
...

つまり、SWIG は OGRSFDriverH を単に void* に変換します。タイプ名を保存する必要があります。どうすればできますか?

また、最初の引数で const を失いますが、これは次の質問です。

4

1 に答える 1

1

私があなたの質問を正しく理解していると仮定すると、C では実際にはtypedefs tovoid*である不透明な「ハンドル」がいくつかありますが、生成されたインターフェイスでは、より強力な型チェックを実施したいと考えています。(C を正確に反映する使用法を許可するという点で、ここではデフォルトの動作が正しいことに注意してください)。ある種類のハンドルが、「別の」引数を取る関数に誤って与えられるのを防ぎたい、つまり、 を一種の強力な typedefvoid*として公開したい。typedef

SWIG を使用すれば、それほど問題なく実行できます。覚えておくべき重要なことは、最終的に生成されるコードが正しくて合法である限り、 SWIG に渡すインターフェイス ファイルが常に実際のC 型と正確に一致する必要はないということです。

これを説明するために例をまとめました。おそらく、原則としてogr_api.hに似ているヘッダーファイルを指定します。

#include <stdio.h>

typedef void * HandleType1;
typedef void * HandleType2;

void foo(HandleType1) {printf("foo\n");}
void bar(HandleType2) {printf("bar\n");}

とでのみ呼び出すことができるようにする必要がfooあります。HandleType1barHandleType2

このような動作を取得するために、次のインターフェイスを使用しました。

%module test

%{
#include "test.h"
%}

%nodefaultctor HandleType1;
struct HandleType1 {};
%nodefaultctor HandleType2;
struct HandleType2 {};

void foo(HandleType1*);
void bar(HandleType2*);

%inline {
  // just for testing - presumably you have a creator in your real API
  HandleType1* geth1() { return NULL; }
  HandleType2* geth2() { return NULL; }
}

これによって生成されるコードはまったく問題ありませんが、実行できないことは何も実行しようとせず、void*どちらもラッパー内で単なるポインターとして処理されます。

これ%nodefaultctorは、SWIG が私たちが伝えた嘘に基づいて新しいハンドルを構築しようとするのを防ぐために必要です。これがないと、コンパイラ エラーが発生します。(おそらく、デストラクタも抑制するか、それが を呼び出すのでカスタマイズする必要がありますfree)。

これにより、各関数に正しいハンドルのみを使用できる Java インターフェイスが生成されます。私はこれをテストしました:

public class run {
  public static void main(String[] args) {
    System.loadLibrary("test");
    test.foo(test.geth1());
    //test.bar(test.geth1());
    //test.foo(test.geth2());
    test.bar(test.geth2());
  }
}

ちょっとしたトリックですが、うまくいきます。生成されるラッパーを見て、自分自身を納得させてください。

これは期待どおりにコンパイルおよび実行されました。コメントアウトされた行は、期待どおりにエラーを返します。


私が理解しているD固有のソリューションの場合typedef、強力なtypedefが得られます( Caliasのようなものとは異なりtypedefます)。次のようなものを使用できると思います。

%module test

typedef void * HandleType1;
typedef void * HandleType2;

%pragma(d) proxydmodulecode = %{
  typedef void * HandleType1;
  typedef void * HandleType2;
%}

%typemap(dtype) HandleType1* "HandleType1";
%typemap(dtype) HandleType2* "HandleType2";

void foo(HandleType1* h1);
void bar(HandleType2* h2);

必要なインターフェイスを生成します。タイプマップは、D インターフェイスで使用される型を変更し、生成されたインターフェイスの (プロキシ) 部分に%pragma挿入します。typedef

于 2012-07-22T17:11:22.980 に答える