我有一个调用我的 C++ 代码的 native 函数调用,此代码创建了我的用户定义类的一个实例。
此函数具有以下签名:
public native Object loadEngine(int arg);
进行此调用后,我想调用更多 native 函数,这些函数将获取从 loadEngine() 返回的“对象”并对其进行修改,或从中请求数据。
签名示例:
public native String loadEngine(Object engine, int queryID);
- 甚至可以这样做吗?
- 如果可能,我如何将我的 GameEngine 数据类型转换为 java Object 或 jni jobject。
- Java 会自动将其作为引用传递,这样它就永远不会被复制,我将能够修改它,对吗?
以下场景会生成一个错误,指出它无法将 GameEngine 转换为 jobject,这是可以理解的,但这是我对 Java 经验很少的最佳选择:
JNIEXPORT jobject JNICALL Java_package_loadEngine
(JNIEnv *env, jobject obj, jint arg) {
GameEngine engine(params);
return (jobject)engine;
}
JNIEXPORT jstring JNICALL Java_package_queryAction
(JNIEnv *env, jobject obj, jobject engine, jint arg) {
String ret = newString(Integer.toString((GameEngine)engine.unimportant()));
return ret;
}
由于我通过 jni 将 native java 代码调用到 c++,不幸的是我无法将 native 函数定义为:
public native GameEngine loadEngine(int arg);
可以理解,但我似乎无法找出解决方法。
谢谢,斯嘉丽。
最佳答案
您可以创建包含、拥有和管理 native 代码的 Java 包装器类。例如(脱离我的头脑,大脑编译):
class GameEngine {
private long nativeGameEnginePointer;
private native long loadEngine();
public GameEngine() {
super(...);
nativeGameEnginePointer = loadEngine();
}
private native void destroyEngine(long nativePointer);
protected void finalize() throws Throwable {
try {
destroyEngine(nativeGameEnginePointer);
} finally {
super.finalize();
}
}
private native double nativePlayGameOrWhatever(long nativePointer);
public double playGameOrWhatever() {
return nativePlayGameOrWhatever(nativeGameEnginePointer);
}
}
并且在您的 JNI 实现中:
class CxxGameEngine;
JNIEXPORT jlong JNICALL GameEngine_loadEngine(JNIEnv *env, jobject obj) {
return (jlong)(new CxxGameEngine(params));
}
JNIEXPORT jvoid JNICALL GameEngine_destroyEngine(JNIEnv *env, jobject obj, jlong nativePointer) {
delete (CxxGameEngine *)nativePointer;
}
JNIEXPORT jdouble JNICALL GameEngine_nativePlayGameOrWhatever(JNIEnv *env, jobject obj, jlong nativePointer) {
return ((CxxGameEngine *)nativePointer)->playGameOrWhatever();
}
请注意使用 long
来表示 native 指针。这就是 Java 运行时在需要时这样做的方式(例如在 java.nio
和 java.util.zip
包中。) long
而不是int
确保类型足够宽,即使在 64 位系统上也能容纳一个指针。
关于java - Android NDK/一般 JNI 问题 : Converting object/jobject to c++ user defiend type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10588339/