java - JNI : return an object from Java to C++, 并将其传递回 Java

标签 java c++ pointers java-native-interface

我有一些 Java 方法需要通过 JNI 从 C++ 调用。我的JNI实现是基于
Is it possible to make a Java JNI which calls jdbc?

我的 Java 项目中有两个 java 文件。一个是定义一个类,另一个包含c++将调用的实际方法。

public class MyObject {
    private static int no;
    private static LocalDateTime time;
    private static String status;
    // getters, setters and toString
}

public class ObjectHandler {
    public static MyObject objectReturnToC;

    public static Object methodA (type1 arg1, type2 arg2, type3 arg3) {
        objectReturnToC = new MyObject();
        // setting fields in returnObject according to passed-in parameters
        return objectReturnToC;
    }
    public static void methodB(Object objectReturnedFromC) {
        // access fields in objectReturnedFromC, do computation and store in
    }
}

我在 Visual Studio 2010 中创建了 C++ DLL。有 JVM.cpp、JVM.h、JavaCalls.h 和 JavaCalls.cpp

Java调用.h

#ifdef JAVACALLSDLL_EXPORTS
#define JAVACALLSDLL_API __declspec(dllexport) 
#else
#define JAVACALLSDLL_API __declspec(dllimport) 
#endif

namespace JavaCalls
{
    class JavaCalls
    {
    public:
        static JAVACALLSDLL_API void *javaMethodA(type1, type2, type3);
        static JAVACALLSDLL_API string toString(void **javaObject);
        static JAVACALLSDLL_API void javaMethodB(void **javaObject);
    };
}

Java调用.cpp

namespace JavaCalls 
{
    void *JavaCalls::javaMethodA(type1 arg1, type2 arg2, type3 arg3) 
    {
        // invoke JVM
        // Find class, methodID
        jobject javaObject = CallStaticObjectMethod(jMain, "methodA",...);
        return javaObject;
    }
    void JavaCalls::javaMethodB(void** javaObject) {
        // invoke JVM
        // Find class, methodID
        CallStaticVoidMethod(jMain, "methodB",...);
    }
}

C++ 使用 DLL 调用 Java 方法 A 和方法 B:

int main() 
{
    void* a = JavaCalls::JavaCalls::javaMethodA(arg1, arg2, arg3);
    // doing other stuff and updating fields in a
    JavaCalls::JavaCalls::javaMethodB(static_cast<void**>(a));
}

显然,传递指针并希望它对 C++ 可用是行不通的。但是我应该怎么做才能将 Java 对象保留在 C++ 中并稍后将其传递回 Java?我应该创建一个 C++ 结构并使用 GetObjectField 将 Java 对象字段映射到其中吗?

最佳答案

我不太明白为什么你的代码中需要void**。如果要使界面不透明,只需使用 void*。也不要忘记在返回的 jobject 上调用 NewGlobalRef()DeleteGlobalRef() - 这将防止它被垃圾收集器破坏:

void *JavaCalls::javaMethodA(type1 arg1, type2 arg2, type3 arg3) 
{
    jobject javaObject = CallStaticObjectMethod(jMain, "methodA",...);
    return NewGlobalRef(jMain, javaObject);
}

void JavaCalls::javaMethodB(void* javaObject) {
     CallStaticVoidMethod(jMain, "methodB", static_cast<jobject>(javaObject));
}

// add this method - it should be called when you finish using the object
void JavaCalls::ReleaseObject(void* javaObject) {
     DeleteGlobalRef(jMain, static_cast<jobject>(javaObject));
}

关于java - JNI : return an object from Java to C++, 并将其传递回 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26280316/

相关文章:

c++ - 使用 "<<"将值输入自定义类

c - char* 究竟定义了什么?如果它定义了一个字符串数组,我如何输出单个元素?

java - 高性能高可用性Java EE分布式应用程序的数据通信和同步

java - 简单的网络服务示例 tomEE 不工作

java - 从java运行外部进程的跨平台方式?

java - Hashmaps 卖飞机票 java

c++ - QTabBar 选项卡的内部 QWidgets?

c++ - 有人能给我提供一个设置和检索 unique_ptr 的简单示例吗

c - 如何从c中的void函数返回动态数组?

c - 如何获得与出现次数相对应的字母进行排序?