我刚刚开始了一份新工作。在这里,我们是使用 JNI(用于桥接 C++/Java)的新手。我是 JNI 的新手,所以请原谅我的菜鸟 :)
在我们的 (win32) Java 应用程序中,我们正在加载一个 C++ DLL。在 Java 端,我们有几个“SomeJClass”实例,每个实例都需要访问 DLL 端对应的“SomeCClass”实例。DLL 公开诸如 GlobalDoSomethingInC() 之类的入口点。这里我必须调用Doer::DoSomethingInC()的实例方法。所以我需要一种平滑的方式来映射各自的 this 指针。当 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 );
我想还不错。但是存储对象引用确实很安全。 我的意思是:当 GC 移动对象时会发生什么?
3 我们目前的解决方案确实“有效”。但它属于http://www.codinghorror.com/blog/ :)
谢谢