繁体   English   中英

如何实现从Java调用到C ++的回调函数?

[英]How to implement a callback function that calls from Java to C++?

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

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

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

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";
}

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

当发生回调的时间到了,让Java将函数的地址尽可能长地传递给本地JNI函数。

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

我有一个讨厌的解决方案! 您实际上不需要本机函数指针。 参与者可以调用自己的方法,该方法以本机代码实现。

例如

class CPPNotifyUtil {

    static
    {
        System.loadLibrary ("nastylib");
    }

    public native void notifyCPP(); // implement in CPP   

}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM