簡體   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