JNI与SO简单应用

来源:互联网 发布:知乎100个经典回答 编辑:程序博客网 时间:2024/06/05 17:27

     我也是刚学的,大家就以前探讨下吧:

JNI译为Java本地接口。它允许Java代码和其他语言编写的代码进行交互。在android中提供JNI的方式,让Java程序可以调用C语言程序。android中很多Java类都具有native接口,这些接口由本地实现,然后注册到系统中。

1.首先我们创建一个java文件,这个java文件调用了jni

HelloWorld.java:

class HelloWorld {
static {
System.loadLibrary("HelloWorld");
}
private native void print();
private native int sum(int i, int k);
public static void main(String args[]) {
new HelloWorld().print();
int sum = new HelloWorld().sum(3,4);
System.out.println("sum="+sum);
}

}

2、使用javac命令编译该java文件,在终端输入"javac  HelloWorld.java"。生成HelloWorld.class.



3.生成HelloWorld.h的头文件,这个头文件可以用java虚拟机自动生成。在终端输入"javah  -jni HelloWorld", 生成HelloWorld.h。如果出现编译错误,请检查你的环境变量是否配置正确。在终端执行 java -version命令查看。



HelloWorld.h:

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

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);

/*
* Class: HelloWorld
* Method: sum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_HelloWorld_sum
(JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif



4.现在必须通过本地的方法来实现jni里面定义的方法。这里通过C++来实现。

HelloWorld.cpp:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject) {
printf ("HelloWorld jim.xia!!!!\n");
return;
}

JNIEXPORT jint JNICALL Java_HelloWorld_sum
(JNIEnv * env, jobject, jint i, jint j) {
int k = (int )(i+j);
return (jint) k;
}


5.本地方法实现完毕后,还要将本地方法打包为so文件。我想还需要简单说明一下libxxx.so的命名规则,沿袭Linux传统,lib<something>.so是类库文件名称的格式,但在JavaSystem.loadLibrary(" something ")方法中指定库名称时,不能包括 前缀—— lib,以及后缀——.so。则需要在终端执行命令:



明下:因为在我们的HelloWorld.cpp中是include<jni.h>,因此gcc编译时会到默认的usr/include下面找jni.h库文件。而这个默认路径下是没有jni.h文件。因此引用-I<dir>,这个dir就是自己定义jni.h的位置。一般的情况下指到自己的liunx下的Jdk目录里面都可以找到。上面命令前面-I <dir>jni.h路径,后面的-I <dir>jni_md.h路径。



6.so编译完毕后就需要与我们javaloadpath路径进行绑定。否则在java中调用会找不到so。因此执行下面命名并运行。java-Djava.library.path=.  HelloWorld



ok,一个简单的jni调用例子就完成了。


原创粉丝点击