私はちょうど新しい仕事を始めました。ここでは、JNI(C ++ / Javaのブリッジング用)を初めて使用します。私はJNIを初めて使用するので、私の許しを許してください:)
(win32)Javaアプリでは、C++DLLをロードしています。Java側には、「SomeJClass」のインスタンスがいくつかあります。これらの各インスタンスは、DLL側の「SomeCClass」の対応するインスタンスにアクセスする必要があります。DLLは、GlobalDoSomethingInC()などのエントリポイントを公開します。ここでは、Doer :: DoSomethingInC()のインスタンスメソッドを呼び出す必要があります。したがって、それぞれのthis-pointersをマップするためのスムーズな方法が必要です。また、DLLスレッドが、対応するJavaインスタンスに通知する必要がある興味深いものを検出したときにも同じマッピングを行う必要があります。
私はいくつかの解決策を考えることができますが、私はそれらをあまり好きではありません。私の質問は、これよりも良い方法はありますか?
1 JavaはC:GetNewInstance()を呼び出します。これは、実際には新しいCインスタンスへのポインタであるintを返します。Javaはそれをm_myCInstanceに格納します。次に、JavaはGlobalDoSomethingInC()を呼び出し、1a
// DLL global
void GlobalDoSomethingInC()
{
// retrive this pointer
//calling back to Java:
jobj tmpJ = NewGlobalRef( env, obj );
Doer* myDoer = <reinterpret_cast>( Doer )tmpJ->GetMyCInstance();
myDoer->DoSomething();
DeleteGlobalRef( env, tmpJ );
// Arrrrgh
}
1bまたは:
// for **every call** that Java adds a parameter,
//which is the stored int:m_myCInstance, and
Doer* myDoer = <reinterpret_cast>( Doer )instanceParam->DoSomethingInC();
// Can we do better that this?
2 CからJavaに呼び出す場合、状況はおそらく良く見えます
In the constructor C calls back into Java and stores
the Java instance reference
in a member variable. m_myJInstance.
In all subsequent calls m_myJInstance can be used to call back Java.
In the destructor we need to call DeleteGlobalRef( env, m_myJInstance );
悪くないと思います。しかし、jobject参照を保存することは本当に安全です。 つまり、GCがオブジェクトを移動するとどうなりますか?
3現在のソリューションは「機能」します。しかし、それはむしろhttp://www.codinghorror.com/blog/に属しています:)
ありがとう