注:用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 实例代码

初识JNI

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);
};

初识JNI

注: 其实如果不用java代码生成.h 文件,只需要引用库代码和.dll 库(System.loadLibrary("NDK_C6"));只要你代码和.dll中代码对应上,便可以调用

 

 

相关文章: