Next: , Previous: Synchronization, Up: About CNI


10.14 Invocation

CNI permits C++ applications to make calls into Java classes, in addition to allowing Java code to call into C++. Several functions, known as the invocation API, are provided to support this.

— Function: jint JvCreateJavaVM (void* vm_args)

Initializes the Java runtime. This function performs essential initialization of the threads interface, garbage collector, exception handling and other key aspects of the runtime. It must be called once by an application with a non-Java main() function, before any other Java or CNI calls are made. It is safe, but not recommended, to call JvCreateJavaVM() more than once provided it is only called from a single thread. The vmargs parameter can be used to specify initialization parameters for the Java runtime. It may be NULL. This function returns 0 upon success, or -1 if the runtime is already initialized.

Note: In GCJ 3.1, the vm_args parameter is ignored. It may be used in a future release.

— Function: java::lang::Thread* JvAttachCurrentThread (jstring name, java::lang::ThreadGroup* group)

Registers an existing thread with the Java runtime. This must be called once from each thread, before that thread makes any other Java or CNI calls. It must be called after JvCreateJavaVM. name specifies a name for the thread. It may be NULL, in which case a name will be generated. group is the ThreadGroup in which this thread will be a member. If it is NULL, the thread will be a member of the main thread group. The return value is the Java Thread object that represents the thread. It is safe to call JvAttachCurrentThread() more than once from the same thread. If the thread is already attached, the call is ignored and the current thread object is returned.

— Function: jint JvDetachCurrentThread ()

Unregisters a thread from the Java runtime. This should be called by threads that were attached using JvAttachCurrentThread(), after they have finished making calls to Java code. This ensures that any resources associated with the thread become eligible for garbage collection. This function returns 0 upon success, or -1 if the current thread is not attached.

10.14.1 Handling uncaught exceptions

If an exception is thrown from Java code called using the invocation API, and no handler for the exception can be found, the runtime will abort the application. In order to make the application more robust, it is recommended that code which uses the invocation API be wrapped by a top-level try/catch block that catches all Java exceptions.

10.14.2 Example

The following code demonstrates the use of the invocation API. In this example, the C++ application initializes the Java runtime and attaches itself. The java.lang.System class is initialized in order to access its out field, and a Java string is printed. Finally, the thread is detached from the runtime once it has finished making Java calls. Everything is wrapped with a try/catch block to provide a default handler for any uncaught exceptions.

The example can be compiled with c++ test.cc -lgcj.

     // test.cc
     #include <gcj/cni.h>
     #include <java/lang/System.h>
     #include <java/io/PrintStream.h>
     #include <java/lang/Throwable.h>
     
     int main(int argc, char *argv)
     {
       using namespace java::lang;
     
       try
       {
         JvCreateJavaVM(NULL);
         JvAttachCurrentThread(NULL, NULL);
     
         String *message = JvNewStringLatin1("Hello from C++");
         JvInitClass(&System::class$);
         System::out->println(message);
     
         JvDetachCurrentThread();
       }
       catch (Throwable *t)
       {
         System::err->println(JvNewStringLatin1("Unhandled Java exception:"));
         t->printStackTrace();
       }
     }