Java调用库文件(JNI)(android对此有所改变)
2016-05-17 16:55
204 查看
1.准备java 程序
testdll.java,内容为:
public class testdll {
static {
System.loadLibrary("goodluck"); //载入库名,库的扩展名字究竟是DLL还是SO,由系统自己判断。
}
//还需对将要调用的方法做本地声明,关键字为native。且只需要声明,而不需要具体实现
public native static int get();
public native static void set(int i);
public static void main(String[] args) {
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}
然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
用javac testdll.java编译它,会生成testdll.class。
再用javah testdll,则会在当前目录下生成testdll.h文件,内容如下:
#include
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
在具体实现的时候,我们只关心两个函数原型
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); 和
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
这里JNIEXPORT和JNICALL都是JNI的关键字,函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。
下面我们用testdll.cpp文件具体实现这两个函数;
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件,名字为goodluck.dll。把goodluck.dll拷贝到testdll.class的目录下(或者加入环境变量中),java testdll运行它。
对于最重要得参数传递,字长不一样,因此,需要转换。比如传递字符串,java文件中参数为byte[] param,c文件中为jbyteArray,转换可以如下进行:
jsize theArrayLengthJ = (*env)->GetArrayLength(env,param); //得到本地字长
jbyte * arrayBody = (*env)->GetByteArrayElements(env,param,0);//得到本地元素
char* str=(char *)arrayBody;
main中:
byte[] temp = {0}; //字符串末尾补0
String str= "早上好";
byte[] bb= str.getBytes("gbk");
byte[] lastBB = new byte[str.length + temp.length]; //得到最终要传递得参数
就是在传递字节数组到C程序中时,最后的结尾一定要以0结束。
testdll.java,内容为:
public class testdll {
static {
System.loadLibrary("goodluck"); //载入库名,库的扩展名字究竟是DLL还是SO,由系统自己判断。
}
//还需对将要调用的方法做本地声明,关键字为native。且只需要声明,而不需要具体实现
public native static int get();
public native static void set(int i);
public static void main(String[] args) {
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}
然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
用javac testdll.java编译它,会生成testdll.class。
再用javah testdll,则会在当前目录下生成testdll.h文件,内容如下:
#include
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
在具体实现的时候,我们只关心两个函数原型
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); 和
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
这里JNIEXPORT和JNICALL都是JNI的关键字,函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。
下面我们用testdll.cpp文件具体实现这两个函数;
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件,名字为goodluck.dll。把goodluck.dll拷贝到testdll.class的目录下(或者加入环境变量中),java testdll运行它。
对于最重要得参数传递,字长不一样,因此,需要转换。比如传递字符串,java文件中参数为byte[] param,c文件中为jbyteArray,转换可以如下进行:
jsize theArrayLengthJ = (*env)->GetArrayLength(env,param); //得到本地字长
jbyte * arrayBody = (*env)->GetByteArrayElements(env,param,0);//得到本地元素
char* str=(char *)arrayBody;
main中:
byte[] temp = {0}; //字符串末尾补0
String str= "早上好";
byte[] bb= str.getBytes("gbk");
byte[] lastBB = new byte[str.length + temp.length]; //得到最终要传递得参数
就是在传递字节数组到C程序中时,最后的结尾一定要以0结束。
相关文章推荐
- R文件丢失或R文件无法自动编译
- Android——SharedPreferences存储数据方式
- Android判断当前应用程序处于前台还是后台的两种方法
- android float小数点内2位
- Android 省市县 三级联动(android-wheel的使用)
- Android基础之十五数据存储 之 SQLite数据库的封装
- Android中使用Notification实现应用更新显示下载进度
- Android Studio 快捷键
- Android双击退出
- Android Service完全解析,关于服务你所需知道的一切
- android camera中antibanding是什么功能?
- android ViewPager用作广告轮播
- 玩转Android studio 插件开发、测试、JCenter库发布(3)
- Android开发笔记之属性动画解析
- android 高德地图 java.lang.UnsatisfiedLinkError: Native method not found: com.autonavi.amap.mapcore.MapC
- Retrofit2.0 android.os.NetworkOnMainThreadException解决方法
- Android PDF阅读
- Android onActivityResult获取返回值的用法
- 饿了么开源项目:便捷高效的Android数据持久化存储框架
- Fiddler手机抓包-Android手机