之前道长和小伙伴们分享了一下Android Studio平台下JNI开发:入门使用及常见错误。这里在和小伙伴们分享一下Java传参给C语言。如果对JNI开发还不熟悉可以看一下道长之前分享的。
1.在MainActivity中声明本地方法
// 声明一个本地方法,用native关键字修饰
public native String getStringFromNative();
// 传int值向C
public native int sendInt2C(int x ,int y);
// 传string向C
public native String sendString2C(String s);
// 传int[]向C
public native int[] sendIntArray2C(int[] iNum);
2.向.h文件中添加代码
/*
* Class: com_yushan_jnidemo_MainActivity
* Method: getStringFromNative
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_yushan_jnidemo_MainActivity_getStringFromNative
(JNIEnv *, jobject);
/*
* Class: com_yushan_jnidemo_MainActivity
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_yushan_jnidemo_MainActivity_sendInt2C
(JNIEnv *, jobject, jint, jint);
/*
* Class: com_yushan_jnidemo_MainActivity
* Method: sayHelloInC
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_yushan_jnidemo_MainActivity_sendString2C
(JNIEnv *, jobject, jstring);
/*
* Class: com_yushan_jnidemo_MainActivity
* Method: intMethod
* Signature: ([I)[I
*/
JNIEXPORT jintArray JNICALL Java_com_yushan_jnidemo_MainActivity_sendIntArray2C
(JNIEnv *, jobject, jintArray);
3.向.c文件中添加代码
JNIEXPORT jstring JNICALL Java_com_yushan_jnidemo_MainActivity_getStringFromNative
(JNIEnv *env, jobject obj){
char *str = "String from native C";
return (*env)->NewStringUTF(env, str);
}
// java中的jstring, 转化为c的一个字符数组
char *Jstring2CStr(JNIEnv *env, jstring jstr) {
char *rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "GB2312");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode);
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte *ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0) {
rtn = (char *) malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
// 释放内存
(*env)->ReleaseByteArrayElements(env, barr, ba, 0);
return rtn;
}
// 处理整形相加
JNIEXPORT jint JNICALL Java_com_yushan_jnidemo_MainActivity_sendInt2C
(JNIEnv *env, jobject obj, jint x, jint y) {
return x + y;
}
// 处理字符串追加
JNIEXPORT jstring JNICALL Java_com_yushan_jnidemo_MainActivity_sendString2C
(JNIEnv *env, jobject obj, jstring str) {
char *p = Jstring2CStr(env, str);
char *newstr = "append string";
// strcat(dest, sorce) 把sorce字符串添加到dest字符串的后面
return (*env)->NewStringUTF(env, strcat(p, newstr));
}
// 处理数组中的每一个元素
JNIEXPORT jintArray JNICALL Java_com_yushan_jnidemo_MainActivity_sendIntArray2C
(JNIEnv *env, jobject obj, jintArray arr) {
// 获取arr的长度
int len = (*env)->GetArrayLength(env, arr);
if (len == 0) {
return arr;
}
// 取出数组中第一个元素的内存地址
jint * p = (*env)->GetIntArrayElements(env, arr, 0);
int i = 0;
for (; i < len; i++) {
*(p + i) += 5;
}
return arr;
}
4.在MainActivity中调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.tv);
int[] arr = {2,3,5};
String str = "hello";
String fromNative = getStringFromNative();
int fromInt2C = sendInt2C(5,11);
String fromString2C = sendString2C(str);
int[] fromIntArray2C = sendIntArray2C(arr);
textView.setText(fromNative + ":" +fromInt2C+ ":" + fromString2C + ":" + fromIntArray2C[2]);
}
好了,关于Java传参给C就先说这三种类型的数据,希望能给小伙伴们一些帮助。