JNI

JNI(Java Native Interface),它允许Java代码和其他语言写的代码进行交互。

JNI步骤:

  1. 创建一个类(MyJni.java)
  2. javac 编译该类
  3. javah -jni 产生头文件
  4. 编写本地代码,实现头文件中定义的方法。
  5. Run
public class MyJni {

    static {
        System.loadLibrary("myjni");
    }
    
    /*
     * 使用JNI的关键字native
     * 这个关键字决定我们那些方法能在我们的C文件中使用
     * 只须声明,不必实现
     */
    public native void sayHi(String name);
    
    public static native void add(int num);
    
    public static void main(String[] args) {
        new MyJni().sayHi(null);
        MyJni.add(100);
    }
    
}
F:\workspace\Learn\src>javac org\jni\MyJni.java
F:\workspace\Learn\src>javah -jni org.jni.MyJni

在 F:\workspace\Learn\src 下生成 org_jni_MyJni.h,代码如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_jni_MyJni */

#ifndef _Included_org_jni_MyJni
#define _Included_org_jni_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_jni_MyJni
 * Method:    sayHi
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_jni_MyJni_sayHi
  (JNIEnv *, jobject, jstring);

/*
 * Class:     org_jni_MyJni
 * Method:    add
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_org_jni_MyJni_add
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

编写 jni_MyJniImpl.c,

#include <jni.h>
#include "org_jni_MyJni.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_org_jni_MyJni_sayHi
(JNIEnv *env, jobject obj, jstring name)
{
    printf("From jni_MyJniImpl.c : sayHi. \n");
const jbyte *str;
    str = (*env)->GetStringUTFChars(env, name, NULL);
    if (str == NULL) {
        printf("the string is null.\n");
        return ; /* OutOfMemoryError already thrown */
    }
    printf("the string is %s.\n", str);
    return;
}

JNIEXPORT void JNICALL Java_org_jni_MyJni_add
(JNIEnv *env, jobject obj, jint num){
    printf("From jni_MyJniImpl.c : add. \n");
    return;
}

参数1 - JNIEnv自变量——它是指向类型为JNIEnv_的一个特殊JNI数据结构的指针。JNI数据结构的一个元素是指向由JVM生成的一个数组的指针;该数组的每个元素都是指向一个JNI函数的指针。可从固有方法的内部发出对JNI函数的调用,做法是撤消对这些指针的引用(具体的操作实际很简 单)。每种JVM都以自己的方式实现了JNI函数,但它们的地址肯定位于预先定义好的偏移处。

参数2 - 若方法是实例方法,则为jobject,相当于对象本身,即this。若是静态方法,则指向所在类 jclass。

编译生成动态库myjni.dll

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I F:\Java\jdk1.6.0_25\include –I F:\Java\jdk1.6.0_25\include\win32 -shared -o myjni.dll jni_MyJniImpl.c

运行JNI:把编译好的 dll 放到项目根目录,注意不是代码根目录。

 

posted @ 2013-06-25 15:18  Kyle_Java  阅读(422)  评论(0编辑  收藏  举报