Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Nutzung von Java aus einer C-Anwendung

&pagelevel(4)&pagelevel

Das folgende Beispiel demonstriert die Verwendung des Java-Invocation-APIs (Teil des JNI) für den Aufruf von Java-Programmen aus C heraus. Das gewählte Beispiel ist absichtlich einfach gehalten.

Ein Java-Echo-Programm gebe alle seine Argumente auf die Standard-Ausgabe aus. Aus einem C-Programm wird dieses Java-Programm dann aufgerufen.

Implementierung des Java-Codes

In der Datei Echo.java sei die folgende Klasse definiert:

class Echo {
  public static void main(String[] args) 
  {
    for (int i = 0; i < args.length; i++)
    {
      if (i > 0)
        System.out.print(" ");
      System.out.print(args[i]); 
    } 
    System.out.println(""); 
  } 
} 

Compilieren des Java-Codes

Die oben definierte Java-Klasse kann jetzt einfach mit dem Kommando

javac Echo.java

compiliert werden. Durch Aufruf von


java Echo Das ist ein Versuch

können Sie sich vom Funktionieren des Programms überzeugen.

Implementieren des C-Codes

Das folgende C-Programm soll obiges Java-Programm aufrufen und ihm seine Aufrufargumente dabei übergeben. Besonders zu beachten ist wiederum, dass alle an en übergebe-nen Strings ASCII-codiert sein müssen. Dieses Beispiel wird daher vollständig im ASCII-Modus implementiert und produziert.

Die Datei Echo.c sei nun folgendermaßen implementiert:

#include <jni.h>

int
main(int argc, char *argv[])
{
   JavaVMInitArgs vm_args;
   JavaVMOption options[1];
   JavaVM *jvm;
   JNIEnv *env;
   jint res;
   jclass cls;
   jmethodID mid;
   jobjectArray args;
   int i;
   /*
   ** Prepare VM Options
   */
   options[0].optionString = "-Djava.class.path=.";
   /*
   ** Prepare VM configuration
   */
   vm_args.version = JNI_VERSION_1_4;
   vm_args.nOptions = 1;
   vm_args.options = options;
   vm_args.ignoreUnrecognized = JNI_FALSE;
   /*
   ** Create the Java VM
   */
   res = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args);
   if (res < 0)
   {
     fprintf(stderr,"Can't create Java VM\n");
     exit(1);
   }
   /*
   ** Get class Echo
   */
   cls = (*env)->FindClass(env,"Echo");
   if (cls == NULL)
   {
     fprintf(stderr,"Can't find Echo class\n");
     exit(1);
   }
   /*
   ** Get main method

   */
   mid = (*env)->GetStaticMethodID(env,cls,"main",
                  "([Ljava/lang/String;)V");
   if (mid == 0)
   {
     fprintf(stderr,"Can't find main in Echo\n");
     exit(1);
   }
   /*
   ** Allocate argument array
   */
   args = (*env)->NewObjectArray(env,argc-1,
                (*env)->FindClass(env,"java/lang/String"),NULL);
   if (args == 0)
   {
     fprintf(stderr,"Out of memory\n");
     exit(1);
   }
   /*
   ** Prepare arguments
   */
   for (i=1; i<argc; i++)
   {
     jstring jstr;
     jstr = (*env)->NewStringUTF(env,argv[i]);
     if (jstr == NULL)
     {
        fprintf(stderr,"Out of memory\n");
        exit(1);
     }
     (*env)->SetObjectArrayElement(env,args,i-1,jstr);
   }
   /*
   ** Call Java method
   */
   (*env)->CallStaticVoidMethod(env,cls,mid,args);
   /*
   ** Destroy Java VM
   */
   (*jvm)->DestroyJavaVM(jvm);
   return 0;
}

Das Programm arbeitet in dieser Form nur mit einer Standard-Installation von JENV zusammen. Für den Ablauf mit einer Privat-Installation müssen Sie die Umgebungsvariable JAVA_HOME entsprechend setzen (siehe Kapitel „Umgebungsvariablen").

Übersetzen der C-Source

Die im vorigen Abschnitt implementierte C-Source muss nun mit den richtigen CompilerOptionen übersetzt werden. Für Echo.c muss zusätzlich zu den Standard-Optionen, die weiter oben beschrieben wurden, noch der ASCII-Modus berücksichtigt werden:

cc -c -I<Installations-Pfad>/include \
      -Kllm_keep,llm_case_lower \ 
      -Kworkspace_stack,c_names_unlimited \ 
      -Kliteral_encoding_ascii \
      -Kno_integer_overflow Echo.c

Als Ergebnis steht eine Objekt-Datei zur Verfügung.

Binden und Ausführen der Anwendung

Beim Binden der Anwendung muss berücksichtigt werden, dass der Laufzeit-Adapter von Java mit eingebunden wird und nicht die „normalen“ Laufzeitsysteme.

Mit den folgenden Kommandos kann die Anwendung gebunden werden:

export BLSLIB00='$.SYSLNK.JENV.110.GREEN-JAVA' 
cc -Kno_link_stdlibs -B llm4 -o Echo \
      Echo.o -l BLSLIB

Das Programm kann dann wie jedes andere POSIX-Programm aufgerufen werden. Es benötigt zum Ablauf aber ein unter dem Standard-Installationspfad installiertes JENV. Für die Verwendung eines anderswo installierten JENV muss die Umgebungsvariable JAVA_HOME entsprechend gesetzt werden (siehe Kapitel „Umgebungsvariablen").

Der Aufruf mittels


Echo Das ist ein Java-Echo

führt zu der erwarteten Ausgabe:


Das ist ein Java-Echo

Das Programm wird mit der in Abschnitt „Option zur Auswahl des HotSpot TM VM-Typs" im Abschnitt "java" beschriebenen Default-VM ausgeführt. Durch vorheriges Setzen der Umgebungsvariable JENV_VMTYPE kann der VM-Typ explizit bestimmt werden. Also z.B.:


export JENV_VMTYPE=client

Dies bewirkt, dass die HotSpotTM Client-VM zur Ausführung verwendet wird.