gpt4 book ai didi

c++ - JNI 与 C++ 对象实例

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:01:34 26 4
gpt4 key购买 nike

我刚开始一份新工作。在这里,我们刚开始使用 JNI(用于桥接 C++/Java)。我是 JNI 的新手所以请原谅我的菜鸟:)

在我们的 (win32) Java 应用程序中,我们正在加载一个 C++ DLL。在 Java 端,我们有多个“SomeJClass”实例,每个实例都需要访问 DLL 端相应的“SomeCClass”实例。DLL 公开入口点,例如 GlobalDoSomethingInC()。这里我必须调用Doer::DoSomethingInC()的实例方法。所以我需要一种平滑的方法来映射各自的 this-pointers。当 DLL 线程发现一些有趣的东西需要通知相应的 Java 实例时,我也需要做同样的映射。

我能想到几种解决方案,但我不太喜欢它们。我的问题是,还有比这更好的方法吗?

1 Java 调用 C:GetNewInstance()。这将返回一个 int,它实际上是指向新 C 实例的指针。 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/ :)

谢谢

最佳答案

通常这在某种程度上取决于您的环境。我只用过 KNI,它比 JNI 还要原始。我认为有点丑陋是不可避免的,因为您在两个系统之间混合内存跟踪,其中只有一个有 GC。

一般来说,我发现最好将 C 代码中的所有调用包装在函数中,以处理令人讨厌的转换,我认为这是不可避免的。 (顺便说一句,我在这里使用 C 来表示非 Java 代码)

在C 端,Java 对象的移动绝对是​​一个潜在的问题。这将取决于您的平台,但我希望只要您在库中,就不会发生 Java GC,因此您的对象是稳定的。您需要确定这一点。另一方面,如果不是这样,那你就完蛋了。假设是这种情况,您希望对公开给 JNI 的函数执行相同的解除引用/强制转换操作,以便您可以愉快地在所有调用的函数中使用普通 C 对象。

真正丑陋的地方是,如果您可以让对象超出任何一侧的范围,那么任何一侧都可能持有对您的对象的引用。这里我们在 Java 端使用终结器,在 C 端使用析构函数。它并不漂亮,但我认为这是不可避免的。

所以,简短的回答,它会有点丑陋,隔离两种语言之间的界面周围的丑陋,这样对于大部分工作,无论是哪种语言,您都不必担心这些事情。

还值得为存在于此接口(interface)上的对象创建一个基类,因为在这里您还可以隔离一些丑陋之处。

关于c++ - JNI 与 C++ 对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/796845/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com