• 介绍
本文介绍在Linux下实现JNI的一个例子。实验环境为:Ubuntu 11.10,open-jdk-6,gcc 4.6.1


• 编写调用jni的java类:

public class Hello{



public native void hi();



public native int getInt();



public native String getStr();



public native Person getPerson();



static {



System.loadLibrary("hi");



}



public static void main(String[] args){



Hello hello = new Hello();



hello.hi();

System.out.println(hello.getInt());


System.out.println(hello.getStr());



System.out.println(hello.getPerson().name);



}



class Person{



public String name;



}



}


• 使用javac来编译java类
javac -classpath . Hello.java
• 使用javah来生成C程序对应的头文件Hello.h
javah -classpath . Hello
• 用C语言编写实现hi函数的代码

#include <stdio.h>



#include <jni.h>



#include "Hello.h"



JNIEXPORT void JNICALL Java_Hello_hi(JNIEnv *env, jobject obj){



printf("hi, boy!\n");



}



JNIEXPORT jint JNICALL Java_Hello_getInt(JNIEnv *env, jobject obj){



printf("c return int.\n");



return 123;



}



JNIEXPORT jstring JNICALL Java_Hello_getStr(JNIEnv *env, jobject obj){



printf("c return string.\n");



return (*env)->NewStringUTF(env, "Hello world.");



}



JNIEXPORT jobject JNICALL Java_Hello_getPerson(JNIEnv *env, jobject obj){



printf("c return person.\n");



jclass p_cls = (*env)->FindClass(env, "Person");



jfieldID p_fid_name_id = (*env)->GetFieldID(env, p_cls, "name", "Ljava/lang/String;");



jmethodID p_con_id = (*env)->GetMethodID(env, p_cls, "<init>", "()V");



jobject p = (*env)->NewObject(env, p_cls, p_con_id);



(*env)->SetObjectField(env, p, p_fid_name_id, (*env)->NewStringUTF(env, "Mark"));



return p;



}


• 编译生成Linux下的动态链接库文件libhi.so

gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -shared hi.c -o libhi.so



6.最后运行命令验证是否成功(输出"hi, boy!")



java -Djava.library.path=. -classpath . Hello




javap -s java.lang.String




Exception in thread "main" java.lang.UnsatisfiedLinkError: Hello.hi()V



如果在Windows下用gcc编译需要加额外的参数gcc -Wl,--kill-at -shared -hi.c -o hi.dll




如果在64位系统上编译so库的话,需要在configure的时候加参数:



CFLAGS="-O3 -fPIC" ./configure


• 如何在Windows环境下使用Eclipse(CDT)来查看C源代码
需要添加如下环境变量:


LIBRARY=





C_INCLUDE_PATH=



  • 参考

​http://java.sun.com/docs/books/jni/​