1

I have the Java code below:

public class JavaToC {
    
    protected void hereIsYourCallback(long l, double d, boolean b, Object obj) {
        // this should be implemented by subclasses
    }
    
    public void start() {
        try {
            while(true) {
                Thread.sleep(5000);
                hereIsYourCallback(3L, Math.PI, true, "Hello from Java!"); 
            }
        } catch(InterruptedException e) {
            // NOOP
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

Is it possible to write a C++ code that would somehow trap every JVM call to hereIsYourCallback? Note that this callback would have to come from an embedded JVM instantiated through JNI_CreateJavaVM.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Sure, just provide a class derived from `JavaToc` that declares `hereIsYourCallback()` as `native`, and provide your own implementation. – user207421 Apr 24 '22 at 04:43
  • Ok, but would I start my C++ application through Java (by starting the JVM through the command-line) or would I start my C++ application through a C++ executable (by instantiating the JVM through `JNI_CreateJavaVM`) ??? – Roger Kasinsky Apr 24 '22 at 04:58
  • This sounds like something more easily implemented using a tool like JavaCPP that generates all the JNI code you need: https://github.com/bytedeco/javacpp#creating-callback-functions – Samuel Audet May 08 '22 at 11:12

1 Answers1

0

if you're still looking for a solution: you need to use the RegisterNatives() function in jni.h. With that, you can register functions present on the host (c/c++) environment to native methods on the embedded jvm.

see this question for more informations, but the gist is, supposing a class with a native void printingFromC() method:

create your function like this:

JNIEXPORT void JNICALL printingFromC (JNIEnv* env, jobject thisObject) {
    printf("Hello there!");
}

describe your native methods like this (the first string is the method name in java, doesn't need to match the C/C++ function name:

static JNINativeMethod methods[] = {
    {"printingFromC", "()V", (void*) &printingFromC },
};

Then after loading the class, before calling any native methods, register them:

myCls = (jclass) (*env)->FindClass(env, "my/path/MyClass");
(*env)->RegisterNatives(env, myCls, methods, sizeof(methods)/sizeof(methods[0]));

I hope this helps.

MsxCowboy
  • 31
  • 3