注:用ecplise 开发java application 引用本地方法,访问动态库测试 ,visual studio 编写c语言代码,生成动态链接库:.dll ;由于初步学习,方便和快,在window 环境下,所以用.dll 动态库。
//jni 开发 步骤
// 1.编写native 方法
//2.javah 命令,生成.h 文件
//java.h
//3复制.h文件进c文件
// 4.复制jni.h 和jni_md.h (在java的java/jdk**/include 文件下)
// 5.实现.h 头文件中的声明函数,核心代码
//6.生成一个.dll 动态库(生成->dll 要通过属性把文件生成改成.dll)
//7. 在Java 中加载动态库
// 8.触发native 函数
//静态库和动态库 都是函数库
//静态库,编译的时候直接连接到代码.a
//动态库:.dll/.so 在编译的时候连接到代码中
//在程序运行的时候动态加载进去
//动态库独立开发,不让看库里代码,查看是乱码
一.java 实例代码
public class MainTestJni {
public native static String getStringFromC();
public native String getStringFromC2();
public String key="key";
public native String accessFielsd();
public static int count=10;
//accessStaticFiled
public native void accessStaticFiled();
static {
System.loadLibrary("NDK_C6");
}
public static void main(String[] args) {
System.out.println(getStringFromC());
MainTestJni jni=new MainTestJni();
System.out.println(jni.getStringFromC2());
System.out.println("change before key : "+jni.key);
System.out.println("change after key : "+jni.accessFielsd());
System.out.println("change before key : "+count);
jni.accessStaticFiled();
System.out.println("change after account : "+count);
}
}
c 代码:
#include "stdafx.h"
#include "MainTestJni.h"
//每个native 函数 都至少有两个参数(JNIEnv * , jclass /jobject)
//静态jclass 动态jobject
//静态方法 函数用 jclass
JNIEXPORT jstring JNICALL Java_MainTestJni_getStringFromC
(JNIEnv * env, jclass jclz){
return (*env)->NewStringUTF(env, "C_String");
}
//非静态方法 域 就是Java里面的field
JNIEXPORT jstring JNICALL Java_MainTestJni_getStringFromC2
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env, "C_String2");
};
//基本数据类型
//java -jni -c
//boolean jboolean
//byte jbyte
//char jchar
//short jshort
//long jlong
//float jfloat
//double jdouble
//引用类型
//String jstring
//Object jobject
//基本数据类型的数组
//type[] jTypeArray
//byte[] jByteArray
//引用类型数组
//Object[](Sstring) jobjectArray
//访问非静态域
JNIEXPORT jstring JNICALL Java_MainTestJni_accessFielsd
(JNIEnv *env, jobject jobj){
//jclass
jclass jcl = (*env)->GetObjectClass(env,jobj);
//field
jfieldID fid = (*env)->GetFieldID(env,jcl, "key", "Ljava/lang/String;");
//key -> dongNao key
//得到key对应的值
//GetXXField
jstring jstr = (*env)->GetObjectField(env, jobj, fid);
printf("%s\n", jstr);
char * c_str = (*env)->GetStringUTFChars(env, jstr, NULL);
printf("%s\n", c_str);
char text[30] = "dongNao ";
//生成新的字符串
strcat(text,c_str);
//c->jni
jstring new_str = (*env)->NewStringUTF(env, text);
//修改 setXXFiled
(*env)->SetObjectField(env, jobj, fid, new_str);
//申请就要释放
(*env)->ReleaseStringChars(env, new_str, c_str);
return new_str;
};
JNIEXPORT void JNICALL Java_MainTestJni_accessStaticFiled
(JNIEnv *env, jobject jobj){
//jclass
jclass jclz = (*env)->GetObjectClass(env, jobj);
//field
jfieldID fid = (*env)->GetStaticFieldID(env, jclz, "count", "I");
//int 直接操作
jint count = (*env)->GetStaticIntField(env, jclz, fid);
count++;
(*env)->SetStaticIntField(env, jclz, fid, count);
};
注: 其实如果不用java代码生成.h 文件,只需要引用库代码和.dll 库(System.loadLibrary("NDK_C6"));只要你代码和.dll中代码对应上,便可以调用