2 Ocak 2018 Salı

JNI - C kodundan Java'yı çağırmak

JNI_CreateJavaVM metodu - JVM'i İlklendirmek
Örnek
Şöyle yaparız.
#include <stdio.h>
#include <jni.h>
#include <string.h>


bool HelloWorld::init()
{
  JavaVM* jvm;
  JNIEnv* env;
  JavaVMInitArgs args;
  jint result = JNI_CreateJavaVM(&jvm, &env, (void*)&args);

  //...Various initialization procedures

  return true;
}
Örnek
Şöyle yaparız.
#include <iostream>
#include "jni.h"
int main(){
  JavaVM *jvm;       /* denotes a Java VM */
  JNIEnv *env;       /* pointer to native method interface */
  JavaVMInitArgs vm_args; /* JDK/JRE 9 VM initialization arguments */
  JavaVMOption* options = new JavaVMOption[1];
  options[0].optionString = "-Djava.class.path=/home/aaa/Desktop/Untitled.jar";
  vm_args.version = JNI_VERSION_1_8;
  vm_args.nOptions = 1;
  vm_args.options = options;
  vm_args.ignoreUnrecognized = false;
  /* load and initialize a Java VM, return a JNI interface
   * pointer in env */
  JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
  delete options;
  /* invoke the Main.test method using the JNI */
  jclass cls = env->FindClass("xegerImplementation");
  jmethodID mid = env->GetStaticMethodID(cls, "giveMeString", "(I)V");
  env->CallStaticVoidMethod(cls, mid);
  /* We are done. */
  jvm->DestroyJavaVM();
}
Örnek
Windows'ta dizin şöyle
C:\Program Files\Java\jdk1.8.0_121\include\win32
C:\Program Files\Java\jdk1.8.0_121\lib
Linux'ta derlemek için şöyle yaparız.
g++ -g
  -I/usr/lib/jvm/java-8-oracle/include/
  -I/usr/lib/jvm/java-8-oracle/include/linux/
  -L/usr/bin/java
  -L/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/
  main.cpp -o main -ljvm
Linux'ta linklemek için şöyle yaparız.
-L/path/to/java/jre/lib/<arch>/<server or client> -ljvm
Örnek  - static metod çağrımak
Şöyle bir Java sınıfımız olsun.
public class CECUtils {
  public static void onResponse(int opcode) {
    ...
  }
}
Bu Java sınıfını C kodunda çağıran basit bir örnek şöyle
void cec_debug_msg(JNIEnv *env, cec_rx_message_t* msg) {
  jclass cls = (*env)->FindClass(env, "com/example/utils/CECUtils"); (1)
  if(!cls) {
    LOGE("Could not find the CEC class.");
  } else {
    jmethodID methodid = (*env)->GetStaticMethodID(env, cls,
                                                   "onResponse", "(I)V"); (2)
    if(!methodid) {
      LOGE("Could not find the callback method.");
    } else {
      LOGV("Called static void method.");
      (*env)->CallStaticVoidMethod(env, cls, methodid, 5); (3)
    }
  }
}
(1) ile sınıf bulunur
(2) ile sınıfın static metodu bulunur
(3) ile metod çağrılır.

GetStaticMethodID için kullanılan metod imzası şöyle bulunur. -s ile signature çıktısı istediğimizi belirtiriz. -p ile private alanları da istediğimizi belirtiriz.

javap -s -p CECUtils
public static void onResponse(int);
Signature: (I)V




Hiç yorum yok:

Yorum Gönder