2009-11-10 29 views
12

我目前在一个项目中同时使用C++和Java,我希望能够发送一个包含在C++中的对象到我的Java接口,以便通过它来修改它一个GUI,然后用C++发回修改。通过JNI返回一个C++类到Java

到目前为止,我一直通过JNI接口向Java返回int或boolean。这一次我必须通过界面发送一个对象。我已经在C++和Java中提供了类似的类定义。 我想知道如何创建对象,以便我可以在Java中使用它。

在C++中,我有:

JNIEXPORT MyObject JNICALL Java_ca_X_Y_Z_C_1getMyObject(JNIEnv* env, jclass, jint number); 

此功能将被Java,以获得从C++侧对象被调用(的对象包含在一个单,方便)。

在Java年底,我做一个简单的调用这个方法,

MyObject anObject = C_getMyObject(3); 

应该还给我新创建的对象。

当我执行实际调用时,Java当前返回一个UnsatisfiedLinkError。哪里不对?

回答

10

这是我选择使用的解决方案:

首先,我会在Java中创建一个类似的对象。然后,从C++中,我会instanciate并传递所有的值。

(C++) 
clazz = env->FindClass("java/lang/Integer"); 
jmethodID method = env->GetMethodID(clazz, "<init>", "(I)V"); 
return env->NewObject(clazz, method, (jint)anInteger); 

但后来我意识到这不是很便携,有点太复杂。

取而代之,我决定返回一个Java解析并用于初始化对象的字符串。

(JAVA) 
String aString = "valuesoftheobject"; 
MyObject myObject(aString); 

MyObject将有一个接受字符串的构造函数。我相信这个解决方案简单而有效。

4

如果您的MyObject类是用C++定义的,那么您将无法使用Java访问其方法。我想尝试限定围绕你的C对象的Java包装类:

Java: 
public C_Object() { 
    handle = createHandle(); 
} 

private native long createHandle(); // or whatever pointer/handle type? 

public void doStuff() { 
    _doStuff(handle); 
} 

private native void _doStuff(long handle); 

如果可以推断一个C API,而不是,你可以尝试JNA

Your UnsatisfiedLinkError可能是上面写的函数名中的额外字符,或者它可能无法处理返回值MyObject

4

你应该看看的另一个工具是SWIG。 SWIG是用于为其他语言(例如Java,Python或C#)生成用于现有C/C++对象的封装器的好工具。它将围绕C/C++对象生成自动的Java包装,并为您完成所有繁重的JNI工作。

我在Xuggler中广泛使用它。要看到一个例子,如果你下载的Xuggler源代码中有一个C++对象的位置:

csrc/com/xuggle/xuggler/IStreamCoder.h 

我定义在这里痛饮接口文件:

csrc/com/xuggle/xuggler/IStreamCoder.i 

当通过痛饮运行它生成一个Java对象(存储在这里)

generate/java/com/xuggle/xuggler/IStreamCoder.java 

然后,我们可以访问从Java该对象容易(当然,我添加一些裁判计数的东西,但是那是相当先进)。希望有所帮助。

艺术