【问题标题】:How to implement a callback function that calls from Java to C++?如何实现从 Java 调用 C++ 的回调函数?
【发布时间】:2014-02-20 16:55:25
【问题描述】:

我有一个本地 C++ 应用程序,它通过 JNI 创建一个 JVM,实例化一个 Java 类(一个 Akka Actor)并在其上调用异步非阻塞函数。我在 C++ 中使用 JNI 执行此操作,请参见下面的 sn-p。

现在,当 Akka 响应到达我的 Akka Actor 时,我需要在 C++ 中得到通知。为此,我需要将本机函数指针传递给 Java,以便 Akka Java Actor 可以在响应到达时回调到 C++。我怎样才能做到这一点?

请注意,在 Akka Actor 中使用线程同步原语是完全错误的,因为如果等待某个监视器被阻塞,Actor 将无法接收消息,例如CountDownLatch

JavaVM* jvm = NULL;
JNIEnv *env = NULL;
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=/home/azg/code/hpcmom/target/1.1.9-SNAPSHOT/hpcmom-cmaes/hpcmom-cmaes-1.1.9-SNAPSHOT.jar";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
JNI_GetDefaultJavaVMInitArgs(&vm_args);

// create JVM
JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args);
if (jvm == NULL) {
    throw std::runtime_error("failed creating JVM");
} else {
    log_info << "succeeded creating JVM";
}

// find CmaesClient class
jclass cmaesClass = env->FindClass("com/sfoam/hpcmom/cmaes/CmaesClient");
if (cmaesClass == NULL) {
    throw std::runtime_error("failed finding CmaesClient class");
} else {
    log_info << "succeeded finding CmaesClient class";
}

【问题讨论】:

    标签: java c++ callback java-native-interface akka


    【解决方案1】:

    在您的本机代码中,将您的回调函数的地址存储在一个 long 中。将 long 传递给您的 Java 代码并将其作为 long 存储在那里。

    当回调发生时,让 Java 将函数的地址作为 long 传递给本机 JNI 函数。

    在本地 JNI 函数中,将 long 转换为函数指针,然后调用它。

    【讨论】:

      【解决方案2】:

      我有一个讨厌的解决方案!您实际上并不需要本机函数指针。演员可以只调用它自己的方法,该方法在本机代码中实现。

      例如

      class CPPNotifyUtil {
      
          static
          {
              System.loadLibrary ("nastylib");
          }
      
          public native void notifyCPP(); // implement in CPP   
      
      }
      

      请注意,这将涉及创建您的应用程序链接到的另一个本机库(讨厌的)。这将成为您的 dll 的入口点,但不是您的主应用程序。您需要在本机 dll 中有一个方法,该方法允许您注册侦听器以返回您希望收到通知的位置。

      只要确保调用本机方法的任何类和您的主应用程序位于同一台计算机上即可。这适用于任何解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        • 1970-01-01
        • 1970-01-01
        • 2015-03-15
        • 2023-03-14
        • 1970-01-01
        相关资源
        最近更新 更多