JNI是Java Native Interface
的縮寫胆绊,是為了在Java上能夠調(diào)用本地語(yǔ)言尤其是C
和c++
設(shè)計(jì)的。
下面就看下如何在Mac OS
上面如何使用JNI
的調(diào)用C語(yǔ)言篮幢。
編寫Java類
先定義一個(gè)Java
類
public class MacJni {
public native void sayHello();
static {
System.loadLibrary("macjni");
}
public static void main(String[] args) {
MacJni macJni = new MacJni();
macJni.sayHello();
}
}
這里定義了一個(gè)MacJni
的類慷嗜,在它的main函數(shù)中調(diào)用了定義的native
的方法sayHello颂斜。
在static中加載native
的類庫(kù)macjni
,注意JNI的動(dòng)態(tài)庫(kù)在linux上面的命名是.so
文件夫壁,而在Mac OS
上面的命名是.jnilib
,類庫(kù)的名字需要加上lib,也就是在Mac OS
上面動(dòng)態(tài)庫(kù)的名稱應(yīng)該是libmacjni.jnilib
生成.class
通過(guò)命令生成.class
文件:
javac MacJni.java
這樣就可以生成了一個(gè)MacJni.class
的文件。
生成.h文件
通過(guò)命令可以直接生成.class
對(duì)應(yīng).h
文件:
javah MacJni
生成了一個(gè)MacJni.h
的文件沃疮。文件內(nèi)容如下:
* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MacJni */
#ifndef _Included_MacJni
#define _Included_MacJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MacJni
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MacJni_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
該文件定義了一個(gè)方法Java_MacJni_sayHello
,這個(gè)方法對(duì)應(yīng)定義的native方法public native void sayHello();
盒让。
JNI在C語(yǔ)言
中定義的規(guī)則是:Java_包名_類名_方法名
編寫.c文件
根據(jù)定義.h
方法,需要編寫一個(gè)一個(gè).c文件MacJni.c司蔬,用來(lái)實(shí)現(xiàn).h
中的方法
#include <stdio.h>
#include "MacJni.h"
JNIEXPORT void Java_MacJni_sayHello(JNIEnv * env, jobject obj){
printf("hello from jni");
}
這個(gè)方法很簡(jiǎn)單就是打印一句話:hello from jni
邑茄。
編譯.c
在MacJni.h
中有一句話
#include <jni.h>
jni.h
是jdk中C語(yǔ)言庫(kù)的頭文件,在編譯.c的時(shí)候需要指定jni.h的所在俊啼。在Mac OX中他所在的位置是:
/System/Library/Frameworks/JavaVM.framework/Headers
使用gcc
編譯:
gcc -I/System/Library/Frameworks/JavaVM.framework/Headers -c MacJni.c
就可以得到一個(gè)編譯好的文件MacJni.o
,下面需要把.o文件
打包成動(dòng)態(tài)庫(kù)
肺缕。
打包動(dòng)態(tài)庫(kù)
使用gcc
可以直接打包動(dòng)態(tài)庫(kù)
gcc -dynamiclib -o libmacjni.jnilib MacJni.o
把.o文件打包成了libmacjni.jnilib
,就可以通過(guò)Java調(diào)用C語(yǔ)言了。
java MacJni
hello from jni