前文参考:http://www.gaohaiyan.com/3695.html
java数据类型和jni数据类型对照:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Java类型 JNI类型(注意有的带分号) boolean Z byte B char C short S int I long J float F double D // L表示数据类型是引用类 String L/java/lang/String; int[] [I Object[] [L/java/lang/Object; String[] [L/java/lang/String; |
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class MyTest { static { System.loadLibrary("JniTest"); } public String name = "张三"; public static int age = 33; // 私有方法也可被jni调用到 private int methodInJava(int arg1, String arg2) { System.out.println("---> java收到参数:" + arg1 + "," + arg2); return 103; } // 私有方法也可被jni调用到 private static void staticMethodInJava() { System.out.println("===> java的静态方法"); } public native void changeJavasField_Name(); // 从jni改变java对象的属性 public native void changeJavasStaticField_Age(); // 从jni改变java类的静态属性 public native String printLog(String log); // java向jni传参 public native String callJavaMethod(); // 在jni中调用java实例的方法 public static native void CallStaticJavaMethodFromJNI(); // 在jni中调用java类的静态方法 } |
在JNI中改变java实例成员变量的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * obj:java实例对象 */ JNIEXPORT void JNICALL Java_MyTest_changeJavasField_1Name(JNIEnv *env, jobject obj) { jclass clazz = env->GetObjectClass(obj); // 1.拿到java对象的类 // 第3个参数叫‘签名’ 即属性的数据类型:"Ljava/lang/String;"是java属性的数据类型String,注意带个分号。 jfieldID filedID = env->GetFieldID(clazz, "name", "Ljava/lang/String;"); // 2.拿到java对象的属性ID jobject nameObj = env->GetObjectField(obj, filedID); // 3.拿到属性 jstring name = (jstring)nameObj; // 4.拿到java的String型属性 char *str = (char *)(env->GetStringUTFChars(name, 0)); // 属性的初始值 cout << "java中的name " << str << endl; jstring new_name = env->NewStringUTF("李四"); env->SetObjectField(obj, filedID, new_name); // 5.更新java的属性 cout << "从jni设置java成员变量结束" << endl; } |
在JNI中改变java静态成员变量的值
1 2 3 4 5 6 7 8 9 |
JNIEXPORT void JNICALL Java_MyTest_changeJavasStaticField_1Age(JNIEnv *env, jobject obj) { jclass clazz = env->GetObjectClass(obj); // 1.拿到java对象的类 // 第3个参数:"I"是java属性的数据类型int。 jfieldID filedID = env->GetStaticFieldID(clazz, "age", "I"); // 2.拿到java静态属性ID jint age = env->GetStaticIntField(clazz, filedID); // 3.拿到java静态属性的值 cout << "java中的age " << age << endl; env->SetStaticIntField(clazz, filedID, 43); // 4.更新java的静态属性 cout << "从jni设置java静态变量结束" << endl; } |
从java向JNI传递数据
1 2 3 4 5 |
JNIEXPORT jstring JNICALL Java_MyTest_printLog(JNIEnv *env, jobject obj, jstring str) { char *msg = (char *)env->GetStringUTFChars(str, 0); // 将java的String转为jni的char*字符串 cout << "JNI收到:" << msg << endl; return env->NewStringUTF("JNI谢谢了"); // 返回一个java可用的String } |
在jni中调用 java实例 的方法
public、private都可以调用到。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
JNIEXPORT jstring JNICALL Java_MyTest_callJavaMethod(JNIEnv *env, jobject obj) { jclass clazz = env->GetObjectClass(obj); // 1.拿到java实例的Class // 第3个参数叫‘签名’ 即方法的参数数据类型和返回值数据类型,对应目标java成员方法的参数是(int, String),返回值int jmethodID methodID = env->GetMethodID(clazz, "methodInJava", "(ILjava/lang/String;)I"); // 2.拿到java实例方法的ID jstring arg = env->NewStringUTF("vcvcvcvcvcvcv"); jint r = env->CallIntMethod(obj, methodID, 25, arg); // 3.调用java实例方法,并传参 cout << "jni中拿到java实例方法结果:" << r << endl; string s2 ="Hello " + to_string(200); const char *b = s2.data(); jstring str = env->NewStringUTF(b); return str; } |
从jni调用java的静态方法
public、private都可以调用到。
1 2 3 4 5 6 7 8 9 |
/* * clazz:java类,Class。 */ JNIEXPORT void JNICALL Java_MyTest_CallStaticJavaMethodFromJNI(JNIEnv *env, jclass clazz) { // “()V” 一对()里没有东西,表示无参,V表示无返回值 jmethodID methodID = env->GetStaticMethodID(clazz, "staticMethodInJava", "()V"); // 1.拿到java静态方法的ID env->CallStaticVoidMethod(clazz, methodID); // 2.调用java静态方法 cout << "jni调用了java静态方法" << endl; } |
在jni中创建并调用java对象
和MyTest.java、JniTest.cc文件同目录下有ObjectInJni.java文件
1 2 3 4 5 6 7 8 9 10 11 |
public class ObjectInJni { public ObjectInJni(){ System.out.println("java对象被创建"); } public void objShow(){ System.out.println("在jni中创建的java对象,调用实例方法"); } public static void staticShow(){ System.out.println("java类的静态方法"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
JNIEXPORT void JNICALL Java_MyTest_CreateJavaObjectInJNI(JNIEnv *env, jclass clazz) { // jclass klass = env->GetObjectClass(obj); // 如果有参数传入某个obj jclass klass = env->FindClass("ObjectInJni"); // 1.获取class jmethodID constructorMethodId = env->GetMethodID(klass, "<init>", "()V"); // 2.获取构造方法。要用“<init>”,别用类名 jobject objectInJni = env->NewObject(klass, constructorMethodId); // 3.通过构造方法,创建对象 jmethodID objShow = env->GetMethodID(klass, "objShow", "()V"); // 4.获取实例方法 env->CallVoidMethod(objectInJni, objShow); // 5.调用实例方法 jobject java_object = env->AllocObject(klass); // 创建新Java对象但不调用该对象的任何构造函数 env->CallVoidMethod(java_object, objShow); // 6.调用实例方法 jmethodID staticShow = env->GetStaticMethodID(klass, "staticShow", "()V"); // 7.获取静态方法 env->CallStaticVoidMethod(klass, staticShow); // 8.调用静态方法 } |
在jni中创建java String
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
JNIEXPORT void JNICALL Java_MyTest_CreateJavaStringInJNI(JNIEnv *env, jclass clazz) { // 方法1,使用char* const char* jni_str = "Hello这个是字符串"; // c++的字符串 jstring java_str = env->NewStringUTF(jni_str); // jni(java)的字符串 cout << "释放前:" << java_str << endl; const char* jni_str2= (char *)env->GetStringUTFChars(java_str, 0); // java字符串转c++字符串 env->ReleaseStringUTFChars(java_str, jni_str2); // 释放本地内存。ReleaseStringXXX通常和GetStringXXX配对 cout << "释放后:" << jni_str2 << endl; // 方法2,使用string # include <string> string s2 = "Hello " + to_string(200); // c++的string。与数字相连接 const char *b = s2.data(); // string转char* jstring str = env->NewStringUTF(b); // char*转String cout << "创建jstring:" << str << endl; // 方法3,使用jcharArray和java的String const char* p="jni创建的String"; int len = strlen(p); // # include<cstring> jcharArray chararr = env->NewCharArray(len); env->SetCharArrayRegion(chararr, 0, len, (jchar*)p); jclass jstr_class = env->FindClass("java/lang/String"); jmethodID constructMethod = env->GetMethodID(jstr_class, "<init>", "([C)V"); jobject jstrobj = env->NewObject(jstr_class, constructMethod, chararr); jstring jstr = (jstring)jstrobj; cout << "创建String3:" << jstrobj << endl; } |
- end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/3709.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设