2016-04-26 16 views
0

まず最初に、いくつかの一致する質問を見つけましたが、満足できる答えは見つかりませんでした。それらのほとんどはポインタからポインタへの引数をカバーしています(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の経験が全くないので、今私はかなり固執しています。

答えて

0

これは典型的なことですが、私が質問した直後に、私は自分の瞬間を得て、問題点を見つけました。

私はJNI呼び出しで完全修飾クラス名を使用する必要があります。

jclass clazz = jenv->FindClass("com/test/Butler"); 

代わりの

jclass clazz = jenv->FindClass("Butler"); 
関連する問題