一、Java类中声明本地方法,使用native关键字
public class MyNative {
public void showParms(String s, int i, boolean b) {
showParms0(s, i, b);
}
public int hypotenuse(int a, int b) {
return hypotenuse0(a, b);
}
public void setArray(boolean[] ba) {
for (int i = 0; i < ba.length; i++)
ba[i] = true;
setArray0(ba);
}
public void showStrings(String[] sa) {
showStrings0(sa);
}
public String[] getStrings() {
return getStrings0();
}
private native void showParms0(String s, int i, boolean b);
private native int hypotenuse0(int a, int b);
private native void setArray0(boolean[] ba);
private native void showStrings0(String[] sa);
private native String[] getStrings0();
static {
System.loadLibrary("MyNative");
}
public static void main(String[] args) {
MyNative obj = new MyNative();
obj.showParms("Hello", 23, true);
obj.showParms("World", 34, false);
System.out.println(obj.hypotenuse(3, 4));
System.out.println(obj.hypotenuse(9, 12));
boolean[] ba = new boolean[5];
obj.setArray(ba);
for (int i = 0; i < ba.length; i++)
System.out.println(ba[i]);
String[] sa = new String[] { "Hello,", "world!", "JNI", "is", "fun." };
obj.showStrings(sa);
obj.showStrings(obj.getStrings());
}
}
loadLibrary
public static void loadLibrary
(String
libname)
Loads the system library specified by the
libname argument. The manner in which a library name is mapped to the actual system library is system dependent.
The call System.loadLibrary(name) is effectively equivalent to the call
Runtime.getRuntime().loadLibrary(name)
Parameters:
libname - the name of the library.
Throws:
checkLink method doesn't allow loading of the specified dynamic library
See Also:
二、生成.class文件,并使用javah命令,将.class文件生成.h文件
javac MyNative.class
javah -jni MyNative
生成的.h文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class MyNative */
#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyNative
* Method: getStrings0
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_MyNative_getStrings0
(JNIEnv *, jobject);
/*
* Class: MyNative
* Method: showStrings0
* Signature: ([Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_MyNative_showStrings0
(JNIEnv *, jobject, jobjectArray);
/*
* Class: MyNative
* Method: showParms0
* Signature: (Ljava/lang/String;IZ)V
*/
JNIEXPORT void JNICALL Java_MyNative_showParms0
(JNIEnv *, jobject, jstring, jint, jboolean);
/*
* Class: MyNative
* Method: hypotenuse0
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0
(JNIEnv *, jobject, jint, jint);
/*
* Class: MyNative
* Method: setArray0
* Signature: ([Z)V
*/
JNIEXPORT void JNICALL Java_MyNative_setArray0
(JNIEnv *, jobject, jbooleanArray);
#ifdef __cplusplus
}
#endif
#endif
三、将刚刚生成的.h文件包含在头文件中,并用C语言实现这些本地方法,代码如下
#include
#include
#include "MyNative.h"
JNIEXPORT void JNICALL Java_MyNative_showParms0
(JNIEnv *env, jobject obj, jstring s, jint i, jboolean b)
{
const char* szStr = (*env)->GetStringUTFChars( env, s, 0 );
printf( "String = [%s]/n", szStr );
printf( "int = %d/n", i );
printf( "boolean = %s/n", (b==JNI_TRUE ? "true" : "false") );
(*env)->ReleaseStringUTFChars( env, s, szStr );
}
JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0
(JNIEnv *env, jobject obj, jint a, jint b)
{
int rtn = (int)sqrt( (double)( (a*a) + (b*b) ) );
return (jint)rtn;
}
JNIEXPORT void JNICALL Java_MyNative_setArray0
(JNIEnv *env, jclass cls, jbooleanArray ba)
{
jboolean* pba = (*env)->GetBooleanArrayElements( env, ba, 0 );
jsize len = (*env)->GetArrayLength(env, ba);
int i=0;
// 更改偶数数组元素
for( i=0; i < len; i+=2 )
pba[i] = JNI_FALSE;
(*env)->ReleaseBooleanArrayElements( env, ba, pba, 0 );
}
JNIEXPORT void JNICALL Java_MyNative_showStrings0
(JNIEnv *env, jclass cls, jobjectArray sa)
{
int len = (*env)->GetArrayLength( env, sa );
int i=0;
for( i=0; i < len; i++ )
{
jobject obj = (*env)->GetObjectArrayElement(env, sa, i);
jstring str = (jstring)obj;
const char* szStr = (*env)->GetStringUTFChars( env, str, 0 );
printf( "%s ", szStr );
(*env)->ReleaseStringUTFChars( env, str, szStr );
}
printf( "/n" );
}
JNIEXPORT jobjectArray JNICALL Java_MyNative_getStrings0
(JNIEnv *env, jclass cls)
{
jstring str;
jobjectArray args = 0;
jsize len = 5;
char* sa[] = { "Hello,", "world!", "JNI", "is", "fun" };
int i=0;
args = (*env)->NewObjectArray(env, len, (*env)->FindClass(env, "java/lang/String"), 0);
for( i=0; i < len; i++ )
{
str = (*env)->NewStringUTF( env, sa[i] );
(*env)->SetObjectArrayElement(env, args, i, str);
}
return args;
}
四、书写makefile文件,编译刚才所写的C代码,生成.so文件,Linux环境下(windows,DLL文件)
libMyNative.so:MyNative.o makefile
gcc -Wall -rdynamic -shared -o libMyNative.so MyNative.o
MyNative.o:MyNative.c MyNative.h
gcc -Wall -c MyNative.c -I./ -I/sandbox/JAVA2S/jdk1.6.0_16/include -I/sandbox/JAVA2S/jdk1.6.0_16/include/linux
cl:
rm -rf *.o *.so
其中,“/sandbox/JAVA2S/jdk1.6.0_16”为JDK安装目录
“libMyNative.so”是Java类中
static {
System.loadLibrary("MyNative");
}
静态方法中参数+lib
五、修改.bash_profile文件,配置环境变量,由于生成的.so文件在当前目录下,故
.bash_profile文件设置如下
export LD_LIBRARY_PATH=./
六、执行java MyNative命令,结果如下
Linux下实现Java本地方法(Java调用C)完成。
参考资料:
http://www.ibm.com/developerworks/cn/java/jnimthds/index.html