Question

I found an interesting feature in GCC documentation for C++:

java_interface

This type attribute informs C++ that the class is a Java interface. It may only be applied to classes declared within an extern "Java" block. Calls to methods declared in this interface will be dispatched using GCJ's interface table mechanism, instead of regular virtual table dispatch.

As I understand it will look something like this:

extern "Java" {
    class NativeClass __attribute__((java_interface)) {
        //Implementation on native methods goes here.
    }
}

Does anybody know details about this? How to call methods of NativeClass from Java? Maybe anybody tried it in real live?

Was it helpful?

Solution

GCJ provides two native interfaces for Java: JNI using C and CNI using C++. Since the example you quote uses a class, it has to refer to the latter. The CNI documentation on interfaces only describes how to access interfaces described in Java from C++ code. Your example appears to work the other way round: a class written in C++ which is accessible from Java and serves as a Java interface.

But there are pretty few details about this available, so trial and error will be one way to experiment with this, and looking at the actual GCC sources would be another. If you want to see one example of both the extern "Java" block and the java_interface attribute, have a look at java/lang/Readable.h. It contains the C++ representation of the Java interface java.lang.Readable. As the first line of that file states, it is machine generated. So probably the reason why there is so little documentation is because you aren't supposed to write this stuff yourself. It's just a detail of how GCJ implements CNI. And looking more closely at the above file, it seems they even violate their own documentation, since that Readable.h has the attribute outside the extern block, in contrast to the snippet you quoted.

OTHER TIPS

The first time I met this block type it wasn't for "java" but "C", so I think it's the same interest. The block defined by:

extern "Java"
{
// some java definition
}

is used to specifie to GCC that this block is a java interface. It's use for describe which type of mangling used to define the class. The name mangling is use by gcc to generate function name by parameters, etc... More informations here : http://www.agner.org/optimize/calling_conventions.pdf So you use an extern "Java" when you importe java code with it you can call it juste like any function in C/C++ without specifie the mangled name,. My only use of it was for a dll with some C functions defined into, loaded in a C++ code, so I use an extern "C" to specifie to GCC that the definition of this function don't use name mangling. Well, now how to call a native method in java because all in java is method, all is object, there is no function. First, you have to describe you class in java, all of your functions that you want to do in native langage have to be defined as native : private native void print(); for exemple. Secondly, back in your native code header, you must define the method following the nomenclature :

extern "Java"
{
        JNIEXPORT YourReturnType JNICALL Java_ClassName_MethodName (JNIEnv* env, jobject obj);
}

At least, all method must look like that, cause JNI will send a JNIEnv pointer and a object that will be "this" in the method, if you have other arguments, they must be gave after the 2 basics. Finally, you just have to implement all method in a native code file, always following the norme, like :

 JNIEXPORT void JNICALL Jave_Printer_print(JNIEnv* env, jobject obj)
 {
      printf("Hello world");
 }

Now you can create a Printer object in Java and call print method defined as native. I hope I answered your question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top