JNI 学习笔记
2011-09-16 12:06 youxiachai 阅读(61625) 评论(10) 编辑 收藏 举报1,先把c语言的编译环境搭建好,windows下这里使用mingw
1,mingw具体配置
配置环境变量:
打开:“我的电脑->属性->高级->环境变量->系统变量”编辑如下系统变量:
变量名 变量值
PATH C:\MinGW\bin;
LIBRARY_PATH C:\MinGW\lib
C_INCLUDEDE_PATH C:\MinGW\include
CPLUS_INCLUDE_PATH C:\MinGW\include\c++\3.4.2;C:\MinGW\include\c++\3.4.2\mingw32;C:\MinGW\include\c++\3.4.2\backward;C:\MinGW\include
盘符自己搞定吧…
2,开始第一个JNI
1,JNI的原理图
直接到官方教程那里截的….
2,开始使用JNI
package kg.tom; public class MyJni { //使用JNI的关键字native //这个关键字决定我们那些方法能在我们的C文件中使用 //只须声明,不必实现 public native void display(); public native double sum(double x,double y); //这个是到时候调用我们写好的C文件 //现在用不上 //static { // System.loadLibrary("sum"); //} public static void main(String[] args) { //到时候测试用方法现在用不上 //new MyJni().display(); //System.out.println(new MyJni().sum(2.0, 3.0)); } }
然后,就是返回到我们的java基础了…将我们写好的类,转换成头文件
1,先把写好的类转换成.class文件
2,把.class文件转换成头文件,成功的话就会在src目录下看到.h文件了
打开后你会看到
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class kg_tom_MyJni */ #ifndef _Included_kg_tom_MyJni #define _Included_kg_tom_MyJni #ifdef __cplusplus extern "C" { #endif /* * Class: kg_tom_MyJni * Method: display * Signature: ()V */ JNIEXPORT void JNICALL Java_kg_tom_MyJni_display (JNIEnv *, jobject); /* * Class: kg_tom_MyJni * Method: sum * Signature: (DD)D */ JNIEXPORT jdouble JNICALL Java_kg_tom_MyJni_sum (JNIEnv *, jobject, jdouble, jdouble); #ifdef __cplusplus } #endif #endifnative方法名称转换详解:
英语原文 我的理解… 例子 the prefix
Java_
转换后的native方法全部以Java_为前缀 Java_kg_tom_MyJni_display a mangled fully-qualified class name
接着以类的全名标识(包名+类名) Java_kg_tom_MyJni_display
- an underscore (“_”) separator
以下划线为分隔符(“_”) Java_kg_tom_MyJni_display mangled method name 最后就是方法的名称 Java_kg_tom_MyJni_display
- for overloaded native methods, two underscores (“__”) followed by the mangled argument signature
这个理解不能:直译的话就是对已经读取过的native方法,用双下划线(“__”)标注 没找到 3,就是写我们的C文件了
//必须的头文件jni.h #include <jni.h> //导入我们需要实现的本地方法 #include "kg_tom_MyJni.h" #include <stdio.h> JNIEXPORT void JNICALL Java_kg_tom_MyJni_display (JNIEnv *env, jobject obj) { printf("Hello World tom!!"); return; } JNIEXPORT jdouble JNICALL Java_kg_tom_MyJni_sum (JNIEnv *env, jobject obj, jdouble a, jdouble b) { return a + b; }
4,windows下编译成dll文件,linux下编译成so文件.这里只说windows下的
1,java基础
找到我们的jdk文件夹,然后打开其中的include文件夹,就会看到一些头文件,看下关键的Jni.h头文件在不在,在的话,继续,不在
自行下载一个新的jdk…
2,把C文件编译成dll文件
我们这里使用mingw….你会用VC6也可以用VC6编译…
gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -Id:/java/include –Id:/java/include/win32 -shared -o sum.dll java_sum_native.c
命令 简单介绍 -Wall -D_JNI_IMPLEMENTATION_ 把我们的C文件编译成dll -Wl,--kill-at 因为mingw默认是用@来进行分隔,会导致JNI机制不能读取,所以要删掉..
mingw官网解释Id:/java/include –Id:/java/include/win32 导入我们用的的jni需要的头文件…盘符,文件夹自己修改 -shared -o 输出配置,第一个参数为我们输出的名字(随便起),第二个参数为我们的C文件(随便起)
没出什么提示的话就是成功的了…
4,运行我们的JNI
1,用eclipse的话,我们把编译好的dll放到项目根目录,注意不是代码根目录
//把刚才注释的地方删掉.. //这就是必须的,用来读取我们写好的C语言编译好的dll,后缀是系统自己辨认…千万不要自己写 static { System.loadLibrary("sum"); } //mian方法中 //用底层c代码实现输出..呵呵~~ new MyJni().display(); //用c计算会不会快点呢..呵呵~ System.out.println(new MyJni().sum(2.0, 3.0));输出结果
貌似java本身的输出,优先级比较高??
2,补充一下:
1,我们要运行我们编译的C文件,是与我们创建的类是必须一起存在,
例如:我把MyJni.java删掉,然后另起一个Hello.java能不能直接调用dll中的方法呢?那是肯定不行的..因为,jni需要类名来进行查找
3,JNI映射的数据类型
这里内容比较多…以后用的才记录
作者:游戏阿柴
出处:http://www.cnblogs.com/youxilua
本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
微博联系:新浪微博
用支付宝赞助博主:http://me.alipay.com/youxilua