Search code examples
c++cjava-native-interface

Is it possible to implement a Java Interface in C or C++ using JNI?


Assume a Java library which includes a class, lets call it Foo. This class contains a constructor and two methods:

// constructor
Foo();

// returns a random int
public int bar();

// generates a random int "x" and calls integerGenerated(x)
public void generateInt(IntGeneratorListenerInterface listenerInterface);

This assumes a Java interface IntGeneratorListenerInterface with one method:

void integerGenerated(int generatedInt);

I'm able to call bar() from native C and C++. Here's a C++ example, assuming a properly initialized JNIEnv env:

// instantiate Foo
jclass fooClass = env->FindClass("com/my/package/Foo");
jmethodID constructorMethodID = env->GetMethodID(fooClass, "<init>", "()V");
jobject fooInstance = env->NewObject(fooClass, constructorMethodID);

// call bar()
jmethodID barMethodID = env->GetMethodID(fooClass, "bar", "()I");
jint result = env->CallIntMethod(fooInstance, barMethodID);
printf("%d", result);

What I would like to do is implement the interface IntGeneratorInterface from C/C++ such that when I call generateInt() using similar JNI calls, I can receive the callback in C, like:

void integerGenerated(int x)
{
    // do something with the int
}

My question: Is there any way to implement the Java interface in C/C++, such that I can pass something valid to generateInt(), and have integerGenerated() called in C?

I've looked into JNI's RegisterNatives(), but I believe that would require the Java code to declare and call "native" methods (please correct me if I'm wrong), and I do not have the luxury of modifying the existing Java library. Also note that the trivial Java library is just used here to exemplify my question. I realize such simple functionality can be written just as easily natively.


Solution

  • Yes. Just as you do with any other native methods:

    class NativeRunnable implements Runnable {
        @Override
        public native void run();
    }
    

    And now just use javah to create the header file and implement the function.