jni访问java的属性和方法

来源:互联网 发布:seo教程网 编辑:程序博客网 时间:2024/05/20 11:50

java中native方法

public class JniTest {public String key = "jason";public static int count = 9;public native static String getStringFromC();public native String getString2FromC(int i);//访问属性,返回修改之后的属性内容public native String accessField();public native void accessStaticField();public native void accessMethod();public native void accessStaticMethod();public static void main(String[] args) {String text = getStringFromC();System.out.println(text);JniTest t = new JniTest();text = t.getString2FromC(6);System.out.println(text);System.out.println("key修改前:"+t.key);t.accessField();System.out.println("key修改后:"+t.key);System.out.println("count修改前:"+count);t.accessStaticField();System.out.println("count修改后:"+count);t.accessMethod();t.accessStaticMethod();}//产生指定范围的随机数public int genRandomInt(int max){System.out.println("genRandomInt 执行了...");return new Random().nextInt(max); }//产生UUID字符串public static String getUUID(){return UUID.randomUUID().toString();}//加载动态库static{System.loadLibrary("jni_study");}}
c中对native方法的实现

#define _CRT_SECURE_NO_WARNINGS#include "com_dongnaoedu_jni_JniTest.h"#include <string.h>//#include <Windows.h>//函数实现JNIEXPORT jstring JNICALL Java_com_dongnaoedu_jni_JniTest_getStringFromC(JNIEnv *env, jclass jcls){//WinExec("C:\\Program Files (x86)\\Tencent\\QQ\\Bin\\QQScLauncher.exe",0);//JNIEnv 结构体指针//env二级指针//代表Java运行环境,调用Java中的代码//简单的实现//将C的字符串转为一个java字符串return (*env)->NewStringUTF(env,"C String");}JNIEXPORT jstring JNICALL Java_com_dongnaoedu_jni_JniTest_getString2FromC(JNIEnv *env, jobject jobj, jint num){return (*env)->NewStringUTF(env,"C String2");}//每个native函数,都至少有两个参数(JNIEnv*,jclass或者jobject)//1)当native方法为静态方法时://jclass 代表native方法所属类的class对象(JniTest.class)//2)当native方法为非静态方法时://jobject 代表native方法所属的对象//基本数据//Java基本数据类型与JNI数据类型的映射关系//Java类型->JNI类型->C类型/*boolean jbooleanbyte jbyte;char jchar;short jshort;int jint;long jlong;float jfloat;double jdouble;void void*///引用类型(对象)//String jstring//object jobject//数组,基本数据类型的数组//byte[] jByteArray//对象数组//object[](String[]) jobjectArray//C/C++访问Java的成员//1.访问属性//修改属性keyJNIEXPORT jstring JNICALL Java_com_dongnaoedu_jni_JniTest_accessField(JNIEnv *env, jobject jobj){//jobj是t对象,JniTest.classjclass cls = (*env)->GetObjectClass(env, jobj);//jfieldID//属性名称,属性签名jfieldID fid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");//jason >> super jason//获取key属性的值//Get<Type>Fieldjstring jstr = (*env)->GetObjectField(env, jobj, fid);printf("jstr:%#x\n",&jstr);//jstring -> c字符串//isCopy 是否复制(true代表赋值,false不复制)char *c_str = (*env)->GetStringUTFChars(env,jstr,JNI_FALSE);//拼接得到新的字符串char text[20] = "super ";strcat(text,c_str);//c字符串 ->jstringjstring new_jstr = (*env)->NewStringUTF(env, text);//修改key//Set<Type>Field(*env)->SetObjectField(env, jobj, fid, new_jstr);printf("new_jstr:%#x\n", &new_jstr);return new_jstr;}//访问静态属性JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessStaticField(JNIEnv *env, jobject jobj){//jclassjclass cls = (*env)->GetObjectClass(env, jobj);//jfieldIDjfieldID fid = (*env)->GetStaticFieldID(env, cls, "count", "I");//GetStatic<Type>Fieldjint count = (*env)->GetStaticIntField(env, cls, fid);count++;//修改//SetStatic<Type>Field(*env)->SetStaticIntField(env,cls,fid,count);}//2.访问java方法JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessMethod(JNIEnv *env, jobject jobj){//jclassjclass cls = (*env)->GetObjectClass(env, jobj);//jmethodIDjmethodID mid = (*env)->GetMethodID(env, cls, "genRandomInt", "(I)I");//调用//Call<Type>Methodjint random = (*env)->CallIntMethod(env, jobj, mid, 200);printf("random num:%ld",random);//.....}//静态方法JNIEXPORT void JNICALL Java_com_dongnaoedu_jni_JniTest_accessStaticMethod(JNIEnv *env, jobject jobj){//jclassjclass cls = (*env)->GetObjectClass(env, jobj);//jmethodIDjmethodID mid = (*env)->GetStaticMethodID(env, cls, "getUUID", "()Ljava/lang/String;");//调用//CallStatic<Type>Methodjstring uuid = (*env)->CallStaticObjectMethod(env, cls, mid);//随机文件名称 uuid.txt//jstring -> char*//isCopy JNI_FALSE,代表java和c操作的是同一个字符串char *uuid_str = (*env)->GetStringUTFChars(env, uuid, JNI_FALSE);//拼接char filename[100];sprintf(filename, "D://%s.txt",uuid_str);FILE *fp = fopen(filename,"w");fputs("i love you", fp);fclose(fp);}
访问java中的属性和方法都是固定的格式,访问java中的属性时其中一个参数为属性签名,而属性签名有固定的格式,


访问方法时则要手动生成方法签名
在java的src进入运行窗口输入javah 全类名然后就会产生这个类的所有方法和属性签名,如果不进入文件下,则要输入全路径


系统类可以直接在运行窗口输入javap -s -p 全类名生成


(*env) -> GetStringUTFChars()方法的最后一个参数表示是否copy字符串,copy的值由jni内部决定,一般传入为NULL,如果copy则表示java中和jni操作的不是一个字符串,操作的的java中的复制,如果为false,则java和jni操作的是同一个字符串。也就是变相的指针,表示String的引用是否指向同一个引用。