[TOC]
概述 数据类型 JNI的基础数据类型转换
我们声明一个JNI调用JNI的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class JniBasicType { static { System.loadLibrary ("hello-jni" ); } public static native int callNativeInt (int num) ; public static native byte callNativeByte (byte b) ; public static native char callNativeChar (char ch) ; public static native short callNativeShort (short sh) ; public static native long callNativeLong (long l) ; public static native float callNativeFloat (float f) ; public static native double callNativeDouble (double d) ; public static native boolean callNativeBoolean (boolean value) ; }
修改cmakelist文件
1 2 3 4 5 6 7 8 9 # 添加源文件或者库.根据C++文件,我们要把hello-jni.cpp编译成一个hello-jni的SO add_library ( # Sets the name of the library. hello-jni # 库的名字 # Sets the library as a shared library. SHARED #库的类型 共享库(动态)库、如果是STATIC的话,就是静态库 # Provides a relative path to your source file(s). hello-jni.cpp jni/jni_basic_type.cpp ) # 库的源文件
我们新建了一个jni/jni_basic_type.cpp的文件,但是他依然是hello-jni这个库里面的Native方法
下面是具体代码
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 //===============================学习Jni的基础数据类型======================== /** * 第一个参数:是JNI的ENV环境 * 第二个参数:因为我们这些方法在Jave那边都是静态方法,所以我们这个参数类型是jclass * 如果是实例方法的话,我们使用的是jobject * 后面的参数就是方法是实际参数 */ extern "C" JNIEXPORT jint JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeInt(JNIEnv *env, jclass thiz, jint num) { LOG_D("JAVA int value is %d", num); int c_num = num * 2; return c_num; } extern "C" JNIEXPORT jbyte JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeByte(JNIEnv *env, jclass thiz, jbyte b) { LOG_D("java byte value is %d", b); jbyte c_byte = b + (jbyte) 10; return c_byte; } extern "C" JNIEXPORT jchar JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeChar(JNIEnv *env, jclass thiz, jchar ch) { LOG_D("java char value is %c", ch); jchar c_char = ch + (jchar) 3; return c_char; } extern "C" JNIEXPORT jshort JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeShort(JNIEnv *env, jclass thiz, jshort sh) { LOG_D("java char value is %d", sh); jshort c_short = sh + (jshort) 10; return c_short; } extern "C" JNIEXPORT jlong JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeLong(JNIEnv *env, jclass thiz, jlong l) { LOG_D("java long value is %ld", l); jlong c_long = l + 100; return c_long; } extern "C" JNIEXPORT jfloat JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeFloat(JNIEnv *env, jclass thiz, jfloat f) { LOG_D("java float value is %f", f); jfloat c_float = f + (jfloat) 10.0; return c_float; } extern "C" JNIEXPORT jdouble JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeDouble(JNIEnv *env, jclass thiz, jdouble d) { LOG_D("java double value is %f", d); jdouble c_double = d + 20.0; return c_double; } extern "C" JNIEXPORT jboolean JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeBoolean(JNIEnv *env, jclass thiz, jboolean value) { LOG_D("java boolean value is %d", value); jboolean c_bool = (jboolean) !value; return c_bool; }
JNI的字符串数据类型转换
String就不能像基础数据类型一样直接进行转换了。我们需要通过
因为Java一般都是UTF编码的,所以我们只需要调用
1 env->GetStringUTFChars(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 extern "C" JNIEXPORT jstring JNICALL Java_com_frewen_android_demo_logic_samples_jni_JniBasicType_callNativeString (JNIEnv *env, jclass clazz, jstring jString) { const char *str = env->GetStringUTFChars (jString, 0 ); LOG_D ("传入的Java的String是:%s" , str); int len = env->GetStringUTFLength (jString); LOG_D ("传入的Java的String的长度是:%d" , len); char buff[128 ]; env->GetStringUTFRegion (jString, 0 , len - 10 , buff); LOG_D ("传入的Java的String的Buffer:%s" , buff); env->ReleaseStringUTFChars (jString, str); return env->NewStringUTF ("这是C环境的字符串 %s" ); }
JNI中引用类型的转换