java向native层传递参数
1.传递基本类型参数,可以直接使用
//Java层定义接口
public native static int sum(int a, int b);
//.c文件native层实现
JNIEXPORT jint JNICALL Java_com_hd_jni_JNITest_sum
(JNIEnv *env, jclass jclass1, jint a, jint b) {
return a + b;
}
//activity中测试代码
private void testSum() {
int sum = JNITest.sum(10, 20);
Toast.makeText(JNITestActivity.this, "a+b=" + sum, Toast.LENGTH_LONG).show();
}
2.传递复杂类型参数,需要做一定的转换,如String,Object,Array
(1)传递string
//java层定义接口
public native static String testChangeString(String string);
//native层实现
JNIEXPORT jstring JNICALL Java_com_hd_jni_JNITest_testChangeString
(JNIEnv *env, jclass jclass1, jstring str) {
const char *string = (*env)->GetStringUTFChars(env, str, NULL);
const char *prefix = "hello ";
const char *result = join(prefix, string);
(*env)->ReleaseStringUTFChars(env, str, string);
return (*env)->NewStringUTF(env, result);
}
//测试代码
private void testChangeString() {
String returnstr = JNITest.testChangeString("heihei");
Toast.makeText(JNITestActivity.this, "returnstr=" + returnstr, Toast.LENGTH_LONG).show();
}
(2)传递object
//java层定义接口
public native static String studentToString(Student student);
//native层实现
JNIEXPORT jstring JNICALL Java_com_hd_jni_JNITest_studentToString
(JNIEnv *env, jclass jclass1, jobject obj) {
//根据传入的对象获得对应的class
jclass objClass = (*env)->GetObjectClass(env, obj);
//获得名字
jfieldID nameid = (*env)->GetFieldID(env, objClass, "name", "Ljava/lang/String;");
jstring nameStr = (jstring) (*env)->GetObjectField(env, obj, nameid);
const char *name = (*env)->GetStringUTFChars(env, nameStr, NULL);
__android_log_write(ANDROID_LOG_DEBUG, "123", name);
//获得性别
jfieldID sexid = (*env)->GetFieldID(env, objClass, "sex", "I");
jint sex = (*env)->GetIntField(env, obj, sexid);
char *p = NULL;
if (sex == 0) {
p = " male";
} else {
p = " female";
}
//拼装字符串
const char *result = join(name, p);
__android_log_write(ANDROID_LOG_DEBUG, "123", result);
return (*env)->NewStringUTF(env, result);
}
char *join(char *s1, char *s2) {
char *result = malloc(strlen(s1) + strlen(s2) + 1);//+1 for the zero-terminator
// in real code you would check for errors in malloc here
if (result == NULL) exit(1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
//测试代码
private void testChangeString() {
String returnstr = JNITest.testChangeString("heihei");
Toast.makeText(JNITestActivity.this, "returnstr=" + returnstr, Toast.LENGTH_LONG).show();
}
java对象
package com.hd.jni;
public class Student {
public String name;
public int sex;
public Student(String name, int sex) {
this.name = name;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
(3)传递对象数组
//java层定义接口
public native static String listToString(Object[] datas);
//native层实现
JNIEXPORT jstring JNICALL Java_com_hd_jni_JNITest_listToString
(JNIEnv *env, jclass jclass1, jobject obj) {
jobjectArray jarray1 = (jobjectArray) obj;
jsize len = (*env)->GetArrayLength(env, jarray1);
__android_log_print(ANDROID_LOG_DEBUG, "123", "len=%d", len);
int i = 0;
char *result = "";
for (; i < len; i++) {
jstring str = (jstring) (*env)->GetObjectArrayElement(env, jarray1, i);
const char *elem = (*env)->GetStringUTFChars(env, str, NULL);
result = join(result, elem);
}
return (*env)->NewStringUTF(env, result);
}
//测试代码
private void testArray() {
ArrayList<String> array = new ArrayList<>();
array.add("123");
array.add("456");
array.add("789");
String toString = JNITest.listToString(array.toArray());
Toast.makeText(JNITestActivity.this, "listtoString=" + toString, Toast.LENGTH_LONG).show();
}