4

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?

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. 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. Commented Mar 31 at 17:21

2 Answers 2

5

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 or jobject, 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.

Sign up to request clarification or add additional context in comments.

Comments

4

Yes, 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.

5 Comments

A FFM upcall is calling a Java method from C. So I disagree with this answer. If the C program is the main program, it might be difficult to get an initial handle to Java, however.
@Codo Are you sure? Seems like FFM Upcalls don't provide a direct functionality where native C code can call Java methods. I would really appreciate if you could elaborate your comment and maybe send a link to a documentation.
The typical use of FFM is a downcall: calling a C function from Java (see Calling a C Library Function with the FFM API). The opposite is also available: upcalls for calling Java from C. When dealing with a C library, it's mainly used for callbacks. But it can be used for any call from C code (see Upcalls: Passing Java Code as a Function Pointer to a Foreign Function)
@Codo I think the questioner is looking for an FFM equivalent to JNI's Get[Static]MethodId and Call[Static]<Type>Method functions. But JNI is a native API that's included in the native code. In contrast, the native code doesn't know anything about FFM (it's entirely on the Java side), so there's no equivalent "call Java method" API on the native side. The only choice is passing function pointers. I believe this answer is answering in that context, but I agree it could be clarified that upcall stubs exist, it's just that FFM does not provide a reflection-like API for calling Java methods.
It's possible that the original question was asked in this context. The core problem is getting an initial upcall handle to Java when the main program is written in C, and not upcalls in general. The way your answer is phrased, it's wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.