All examples I've come across for calling a Java method from C using the Foreign Function & Memory API involve callbacks, that is, a Java method that runs some native function with a Java callback as a parameter.
What about C calling a Java method directly? Is JNI still the only way to do that?
All examples I've come across for calling a Java method from C using the Foreign Function & Memory API involve callbacks, that is, a Java method that runs some native function with a Java callback as a parameter.
What about C calling a Java method directly? Is JNI still the only way to do that?
Share Improve this question edited Mar 28 at 18:53 Basil Bourque 341k123 gold badges935 silver badges1.3k bronze badges asked Mar 28 at 17:40 BCartoloBCartolo 7695 silver badges22 bronze badges 2- 2 What's the setup? Is the Java code the main program, or the C program? What's the use case? In the former case, you certainly can use Foreign Function & Memory API and pass function pointers for Java methods that can be called from C. – Codo Commented Mar 28 at 21:20
- We support both ways. Start with C and go to Java, or from Java it goes into C. Yeah I want to explore using FFM for calling C and passing function pointers and what not, but when it comes to C calling Java, looks like what I have will not change. – BCartolo Commented Mar 31 at 17:21
2 Answers
Reset to default 4Yes, as far as I know JNI is still the only option to call a Java method from C. There are no alternatives currently in Project Panama for calling Java from native C.
If you're looking for the equivalent of native functions like GetMethodId, GetStaticMethodId, CallMethod, and CallStaticMethod from Java Native Interface (JNI), then you're out of luck. The Foreign Function & Memory (FFM) API does not provide an equivalent to those native functions. Keep in mind that JNI is a native library that you include in your own native library, which means there's a native API for interacting with the Java virtual machine. Whereas FFM is an entirely Java API. Not only is there no equivalent to CallMethod
and such, there's no equivalent to any of the native API defined by JNI.
Native code written with JNI is inherently aware that it's running in the context of a JVM. But the FFM API is designed to work with arbitrary native code, at least so long as the interface conforms to the ABI of C. Only the Java code is aware it's using the FFM API. The native code has no idea it's part of a Java application, let alone that the FFM API is being used. It has no way of interacting with the JVM directly.
That said, the FFM API provides a way to pass function pointers to native code with upcall stubs in order to call Java methods from native. However, this is not equivalent to JNI:
You have to create the upcall stub in Java and then pass it to the native code via a downcall handle. There's no way to create the upcall stub on the native side.
You are limited to one Java method per upcall stub. And if it's an instance method, you're limited to calling that method on a single specific instance per upcall stub.
In contrast, the JNI functions work nearly the same as reflection, allowing you to call any method of a class or object. You of course need a reference to the
jclass
orjobject
, but you don't necessarily have to get those from the Java side. It's possible to get the desired class or create the object using JNI's native API.
The first two points mean upcall stubs inherently function as callbacks, which is why examples of using upcall stubs demonstrate them as such.