red*_*ike 12 c++ java java-native-interface
我没有在任何地方看到这个(或者我可能很简单没有看到它)但有没有办法使用JNI返回c/c ++对象并在java中使用该对象?
例如(非常简单):
class simpleClass{
...
private:
int intVar;
public:
int getIntVar();
void setIntVar(int someNum);
...
}
Run Code Online (Sandbox Code Playgroud)
在我的java代码中,我将如何执行以下操作:
...
simpleClass sc = new simpleClass();
sc.setIntVar(9);
System.out.println(sc.getIntVar());
...
Run Code Online (Sandbox Code Playgroud)
我意识到这是一个非常简单的例子,但我只是在寻找概念 - 我在c ++中考虑的类是非常大的,我希望避免创建一个TON的包装器方法......
如果它不可能那么好,只是希望节省几天编码大声笑
ped*_*rro 13
您的Java版SimpleClass应该做两件事.一,保留一个私有long值,将C++指针的值存储到后备本机对象(您可能必须使用BigInteger,具体取决于本机指针的大小 - unsigned long long?).二,使公共方法(例如setIntVal)本地化.
public class SimpleClass {
private long nativePtr;
public SimpleClass() {
nativePtr = initNativeSimpleClass();
}
public void destroy() {
destroyNativeSimpleClass();
nativePtr = 0L;
}
protected void finalize() throws Throwable {
destroyNativeSimpleClass();
nativePtr = 0L;
}
public native int getIntVal();
public native void setIntVal(int val);
private native long initNativeSimpleClass();
private native void destroyNativeSimpleClass();
}
Run Code Online (Sandbox Code Playgroud)
然后在JNI代码中实现这些本机方法.该initNativeSimpleClass()方法将新增一个支持C++的实例SimpleClass.destroyNativeSimpleClass()然后该方法将删除该实例.访问器方法将使用值nativePtr,将其强制转换为实际指针,并在本机后备实例上执行适当的操作.
这个成语存在泄漏内存的真正风险,因为类的用户必须在完成实例时调用destroy.如果不这样做,则可能无法正确销毁后备本机实例.正如我在示例中所示,您可以覆盖finalize以调用本机驱逐程序函数,但是关于如何无法依赖finalize的所有警告仍然适用.通过nativePtr在销毁时将值设置为0,如果多次调用destroy,则可以避免seg错误(在C++中删除NULL是安全的).
不,你不能.C++和Java ABI完全不同 - 例如,c ++没有定义一个.实际上,c ++有很多功能无法映射到Java,但这些功能无法正常工作.您如何期望Java能够处理c ++模板?对原始人的指针?不是指针的对象?
现在你可以做的是,使用SWIG为你生成正确的包装器方法 - 这实际上可以工作,并且工作量远远超过你的计划:)