私があなたの質問を正しく理解していると仮定すると、C では実際にはtypedef
s 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
あります。HandleType1
bar
HandleType2
このような動作を取得するために、次のインターフェイスを使用しました。
%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