Next: , Previous: Strings, Up: About CNI


12.13 Interoperating with C/C++

Because CNI is designed to represent Java classes and methods it cannot be mixed readily with C/C++ types.

One important restriction is that Java classes cannot have non-Java type instance or static variables and cannot have methods which take non-Java types as arguments or return non-Java types.

None of the following is possible with CNI:

     
     class ::MyClass : public java::lang::Object
     {
        char* variable;  // char* is not a valid Java type.
     }
     
     
     uint
     ::SomeClass::someMethod (char *arg)
     {
       .
       .
       .
     }   // uint is not a valid Java type, neither is char*

Of course, it is ok to use C/C++ types within the scope of a method:

     jint
     ::SomeClass::otherMethod (jstring str)
     {
        char *arg = ...
        .
        .
        .
     }

12.13.1 RawData

The above restriction can be problematic, so CNI includes the gnu.gcj.RawData class. The RawData class is a non-scanned reference type. In other words variables declared of type RawData can contain any data and are not checked by the compiler or memory manager in any way.

This means that you can put C/C++ data structures (including classes) in your CNI classes, as long as you use the appropriate cast.

Here are some examples:

     
     class ::MyClass : public java::lang::Object
     {
        gnu.gcj.RawData string;
     
        MyClass ();
        gnu.gcj.RawData getText ();
        void printText ();
     }
     
     ::MyClass::MyClass ()
     {
        char* text = ...
        string = text;
     }
     
     gnu.gcj.RawData
     ::MyClass::getText ()
     {
        return string;
     }
     
     void
     ::MyClass::printText ()
     {
       printf("%s\n", (char*) string);
     }

12.13.2 RawDataManaged

gnu.gcj.RawDataManaged is another type used to indicate special data used by native code. Unlike the RawData type, fields declared as RawDataManaged will be "marked" by the memory manager and considered for garbage collection.

Native data which is allocated using CNI's JvAllocBytes() function and stored in a RawDataManaged will be automatically freed when the Java object it is associated with becomes unreachable.

12.13.3 Native memory allocation

— Function: void* JvAllocBytes (jsize size)

Allocates size bytes from the heap. The memory returned is zeroed. This memory is not scanned for pointers by the garbage collector, but will be freed if no references to it are discovered.

This function can be useful if you need to associate some native data with a Java object. Using a CNI's special RawDataManaged type, native data allocated with JvAllocBytes will be automatically freed when the Java object itself becomes unreachable.

12.13.4 Posix signals

On Posix based systems the libgcj library uses several signals internally. CNI code should not attempt to use the same signals as doing so may cause libgcj and/or the CNI code to fail.

SIGSEGV is used on many systems to generate NullPointerExceptions. SIGCHLD is used internally by Runtime.exec(). Several other signals (that vary from platform to platform) can be used by the memory manager and by Thread.interrupt().