part1.JNI介绍:
JNI其实是Java Native Interface的简称,也就是java本地接口。
简单点说就是从java里面可以调用用c/c++实现的函数
part2.例子:打印HelloWorld
文件清单:
1.java类 HelloWorld.java
package com.edie.jni;
class HelloWorld {
public native void print();//#1
public static void main(String[] args) {
HelloWorld test=new HelloWorld();
test.print();
}
static {//#2
System.loadLibrary("HelloWorld");//#3
}
}
tips:
#1 native 声明用c/c++实现的方法;
#2 使用loadLibrary方法装载含有该方法的本地库 HelloWorld.dll 或 libHelloWorld.so(linux下)
#3 static 代码块,使Java VM初始化一个类时,首先执行这部分代码,这可保证调用本地方法前,装载了本地库。
2.com_edie_jni_HelloWorld.h
#include
#ifndef _Included_com_edie_jni_HelloWorld
#define _Included_com_edie_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_edie_jni_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
3.HelloWorld.c文件
#include #include "jni.h"
#include "com_edie_jni_HelloWorld.h"
JNIEXPORT void JNICALL
Java_com_edie_jni_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
windows下调用动态库dll
step0.配置Eclipse环境
Eclipse中的配置:将项目的working directory 设置为工程的bin目录,这样Eclipse自动编译后的*.class文件就会保存的bin下面,并 且生成的头文件也会保存在bin根
目录下。
Vc++中的配置:在Tools->Options->Directories中设置jni.h jni_md.h的路径,%JAVA_HOME%\include及%JAVA_HOME%\include\win32
step1.编译java文件
javac HelloWorld.java 编译java文件,生成.class 文件。
step2.生成java头文件
在工程bin根目录下执行命令
javah -jni com.edie.jni.HelloWorld -jni 为默认参数,可有可无。生成的头文件为:com_edie_jni_HelloWorld.h
关键部分如下:
JNIEXPORT void JNICALL
Java_com_edie_jni_HelloWorld_print (JNIEnv *, jobject);
tips1.com_edie_jni 为HelloWorld.java文件的包路径;
tips2.该函数声明,接受两个参数,第一个参数是指向JNIEnv结构的指针; 第二个参数,为HelloWorld对象自身,即this指针。
补充:ifndef和ifdef的知识 见
step3.根据java头文件生成c文件
在VC++中新建一个Win32 Dynamic-Link library工程,选择An empty DLL project空工程。
我的工程是HelloWorld,把刚刚生成的那个头文件拷贝到这个工程的根目录里。
新建source code:elloWorld.c 实现头文件中的函数Java_com_edie_jni_HelloWorld_print
step4.生成dll文件
F7编译文件,成功后在debug目录中生成HelloWorld.dll文件
step5.运行java文件
将HelloWorld.dll文件复制到工程的bin根目录下,
在Eclipse中运行。
Linux下调用动态库so
step0.配置环境
配置jdk
step1.编译java文件
javac HelloWorld.java -d .
// 将会在当前目录生成包路径com/eide/jni文件夹,如果
// 没有定义-d .那么将直接在当前目录生成HelloWorld.class
step2.生成java头文件
javah com.edie.jni.HelloWorld //必须写完整的包路径,生成com_edie_jni_HelloWorld.h文件
step3.根据java头文件生成c文件
vim创建HelloWorld.c 并引入com_edie_jni_HelloWorld.h头文件
step4.生成so文件
F7编译文件,成功后在debug目录中生成HelloWorld.dll文件;
gcc -fPIC -shared -o libHelloWorld.so HelloWorld.c 生成libHelloWorld.so文件
补充gcc编译参数,见
step5.运行java文件
java -Djava.library.path=. HelloWorld //-Djava.library.path=.指定so文件的位置
./HelloWorld