7

I'm going to write a Java server/client application, in which the client is not really a client (it doesn't have a main), but it's a library.

Aside, I have to develop a C module (a fuse driver) that needs to interact with the server, so it needs to invoke client's function.

I've founded many examples of C functions invoked from Java application, but no one of what I need.

Can you give me a suggest or some hints?

EDIT

because someone could not understand what i need, I want to be more clear: I have a server, and a program can interact with it only using a library, written in Java. The real client is written in C, and it has to be able to invoke the library's functions, so in C I have to call java method

maba
  • 47,113
  • 10
  • 108
  • 118
litiales
  • 171
  • 4
  • 12
  • The functionality that makes it possible to call C code from a Java program is called "JNI". You can find lots of examples with a google search. – Russell Zahniser Apr 13 '13 at 15:23
  • 2
    @RussellZahniser Totally useless comment, as he is trying to call java from c, not c from java. – BackSlash Apr 13 '13 at 15:29
  • @Harlandraka: The C module is clearly the client (it "interacts with the server"), so I read "it needs to invoke client's function" assuming that "it" is the (Java) server. – Russell Zahniser Apr 13 '13 at 15:37
  • 1
    @RussellZahniser he has a C client that needs some Java libraries, JNI allows Java to call C functions, but he wants to do the exact opposite, he wants to call his Java libraries from a C application, so he doesn't need JNI – BackSlash Apr 13 '13 at 15:40
  • 2
    @Harlandeaka The [Invocation API](http://docs.oracle.com/javase/1.4.2/docs/guide/jni/spec/invocation.html) allows you to call Java code from C/C++ and is part of the JNI Spec. – maba Apr 13 '13 at 15:49
  • 1
    If you can't manage to do what maba suggests, you can always 1) create a main() class around the Java library that gets requests from stdin and writes responses to stdout 2) Launch the JVM as a new process from your C client and interact with the wrapped Java library it via stdin/stdout. – gd1 Apr 13 '13 at 15:52
  • 2
    If you're already doing a client-server architecture, why not actually do that? Wiring together ZeroMQ or DBus some other messaging middleware and a serialization library (JSON or Protocol Buffers or Thrift or whatever) should be less persnickety and more maintainable than using raw JNI calls to marshal data structures. – millimoose Apr 13 '13 at 16:08
  • @millimoose good idea! I had not thought to this possibility, and it is actually the best, mainly because my application has to run just on Linux/Unix computers, so I can use Dbus – litiales Apr 13 '13 at 16:21
  • [This question][1] might help. I'ts basically an illustration of the Invocation API. [1]: http://stackoverflow.com/questions/15560572/using-jni-to-execute-a-java-jar-from-a-c-program-using-g-or-eclipse/15560716#15560716 – ldav1s Apr 13 '13 at 16:46

1 Answers1

7

There are essentially two ways to link C and Java code; JNA and JNI.

JNA is typically used for trivial interfaces; binding shared libraries with appropriate signatures for calls from the JVM into C libraries. Some things are not feasible with JNA alone, especially calls to Java methods and direct modification of Java objects at the C side, where one would quickly end up with another layer to pass the modifications up and down. The point is, that the type map is restricted to primitives and some array (buffer/string) types: http://jna.java.net/javadoc/overview-summary.html#marshalling. This layer would most probably consist of less concise code, introducing additional overhead. But still, calls from C functions to Java methods are impossible with JNA alone.

If you need to call Java methods or twiddle around within the JVM's objects 'from below' in C, start with JNI.

From your question, I assume, that you probably want to execute your whole Java <> C facility from the C (native) side rather than from a JVM. In this case, you need to embed a JVM into your C/C++ application using JNI: https://stackoverflow.com/a/7506378/1175253

How to generate C headers for JNI implementation: How to generate JNI header file in Eclipse

Of course, you can (or rather should) implement JNI C functions with C++, it simplifies resource management by using RAII, etc.


Edit

Programming with JNI == playing with fire. Take care of global references at the C side, threads, array pinning, etc. Whether you actually need to use JNI greatly depends on what exactly you want to achieve.

One can retrieve any Java class as well as its methods and fields from the JNIEnv for invocation or modification respectively (just like Java's reflection). Invoking a native Java (JNI) method this way might be dangerous. Assuming, one locks a non-recursive mutex within the C implementation, a nested call could end up in a deadlock. So one typically invokes plain (simple) Java methods from C which neither are native nor call own, native methods themselves, even if just for the sake of proper design. The overhead introduced by JNI is negligible from what I experienced in my recent project.

Community
  • 1
  • 1
Sam
  • 7,778
  • 1
  • 23
  • 49
  • Ok, it could be the way. What I don't understand is if Java methods I need to call have to be written using JNI, or as simple Java methods, and if this perspective is better (in term of performance, maintainability and, of course, designing matters) then using socket – litiales Apr 13 '13 at 16:15
  • 1
    @sam Can tools like Swig.org help here? – Ayyappa Jan 04 '23 at 10:18