まず最初に、いくつかの一致する質問を見つけましたが、満足できる答えは見つかりませんでした。それらのほとんどはポインタからポインタへの引数をカバーしています(C++ではありません)。そして、Javaの代わりにPythonをカバーするものもあります。SWIGとJava:Javaへのオブジェクト出力パラメータへのポインタへのC++ポインタのマッピング方法
私はオブジェクトへのポインタへのポインタである出力パラメータを持つC++メソッドを持っています。私はJavaからこのメソッドを呼び出す必要があります。
JavaでSWIGを使用するためのドキュメントでは、this Butler exampleが見つかりました。それはオブジェクトの代わりに構造体をカバーすることを除いて、私が必要とするものです。また、C++の代わりにCのために書かれています。私はこの例から始めました。私が必要とするものは、この例のように見えるかもしれません(まったく別のアプローチが必要かもしれませんが、とにかく試みました)。
元Cの実装は次のようになります。
class Butler {
// ... necessary class members, getters and setters go here ...
static int HireButler(Butler **ppButler) {
Butler *pButler = new Butler();
pButler->setHoursAvailable(24);
pButler->setGreeting("At your service Sir");
*ppButler = pButler;
return 1;
}
static void FireButler(Butler *pButler) {
delete pButler;
}
};
:私のC++バージョンで
int HireButler(Butler **ppButler) {
Butler *pButler = (Butler *)malloc(sizeof(Butler));
pButler->hoursAvailable = 24;
pButler->greeting = (char *)malloc(32);
strcpy(pButler->greeting, "At your service Sir");
*ppButler = pButler;
return 1;
}
、それはこの(私はバトラークラスのHireButlerとFireButler静的メソッドを作った)ように見えますSWIGのinterfanceファイルについては、例のコードをほぼ完全にコピーしました。
// Do not generate the default proxy constructor or destructor
%nodefaultctor Butler;
%nodefaultdtor Butler;
// Add in pure Java code proxy constructor
%typemap(javacode) Butler %{
/** This constructor creates the proxy which initially does not create nor own any C memory */
public Butler() {
this(0, false);
}
%}
// Type typemaps for marshalling Butler **
%typemap(jni) Butler ** "jobject"
%typemap(jtype) Butler ** "Butler"
%typemap(jstype) Butler ** "Butler"
// Typemaps for Butler ** as a parameter output type
%typemap(in) Butler ** (Butler *ppButler = 0) %{
$1 = &ppButler;
%}
%typemap(argout) Butler ** {
// Give Java proxy the C++ pointer (of newly created object)
jclass clazz = jenv->FindClass("Butler");
jfieldID fid = jenv->GetFieldID(clazz, "swigCPtr", "J");
jlong cPtr = 0;
*(Butler **)&cPtr = *$1;
jenv->SetLongField($input, fid, cPtr);
}
%typemap(javain) Butler ** "$javainput"
私は必要な生成した後:私はJNIはC++の呼び出しCスタイルを変更しなければならなかった場合を除き - - スタイルJNI呼び出し(>と最初の引数をドロップするようにjenv->の代わりに(の* jenv)です) SWIGを使用したJavaおよびC++ラッパーコードはすべてコンパイルされ、Javaコードは良好に見えます。しかし、私は次のJavaコードを実行しようとすると、私は例外を取得:
Butler jeeves = new Butler();
Butler.HireButler(jeeves);
System.out.println("Greeting: " + jeeves.getGreeting());
System.out.println("Availability: " + jeeves.getHoursAvailable() + " hours per day");
バグレポートファイルから、例外はJNIを使用してswigCPtrフィールドを取得する際に起こるようです:
Stack: [0x0000000002590000,0x0000000002690000], sp=0x000000000268f630, free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0x136519]
C [TestDll.dll+0x411f] JNIEnv_::GetFieldID+0x4f
C [TestDll.dll+0x4e05] Java_com_test_exampleJNI_Butler_1HireButler+0x95
C 0x000000000297dcec
残念ながら、私はJNIの経験が全くないので、今私はかなり固執しています。