简体   繁体   中英

How to send data back to C app from Java app launched via Invocation API using JNI?

I have a Java app acting as GUI launched via the Invocation API for C

MyApp.c -> Main application - compiled to MyApp
MyGUI.java -> Java GUI launched programmatically from the C main application - compiled to MyGUI.class
MyGUI_Print.c -> holds JNI method for testing purpose, called from Java GUI - compiled to libMyGUI_Print.so

The main C (MyApp) file looks like.:

 #include <jni.h>   
//...
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
//...
(*env)->CallStaticVoidMethod(env, cls, mid, args);

the last line method call makes me able to send data from C to the programmatically launched Java GUI. But how do I send data (boolean or string) back to the actual C app (MyApp) from Java - let's say on a button click in the Java GUI?

It's clear that I can call C methods from within Java via JNI. The Java GUI app (MyGUI) holds for testing purposes:

private native void print();
static {
   System.loadLibrary("MyGUI_Print");
}

But the corresponding C file has to be compiled as so/dll file, so I have of course no connection between this library file (MyGUI_Print) and the actual c program (MyApp) I need the data in. From the MyGUI_Print I'm however able to print like this:

#include <jni.h>
#include <stdio.h>
#include "MyGUI.h"

JNIEXPORT void JNICALL Java_MyGUI_print (JNIEnv *env, jobject obj)
{
    printf("Hello World!");
    fflush(stdout);
}

This output is also reaching the actual C app's console output. But the C app itself has so far no knowledge of the "incoming" data. Any way I can programmatically access this string on the other side (C app)? Or is there any better solution?

Theoretically I could of course do polling - ie asking from the C app every few seconds the current state of some variable in the Java environment. But I don't think that's a nice way of doing it.

Actually you do have a connection between your executable and a hypothetical JNI library. They're in the same process so you can always pass some handle from C code to Java code and then from Java code to the C code in your JNI library. And the library can use it to call stuff from you main module.

That said, I would skip the JNI part altogether. You could pass a function address to Java, then use JNA ( https://github.com/java-native-access/jna ) to call that function. It uses libffi internally.

(If you don't want to pass function pointers around, JNA can also help you get the module handle for wherever your function is and then get the function via its name)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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