您的位置:首页 > 移动开发 > Android开发

Android的JNI【实战教程】3⃣️--Java调用C代码

2017-03-29 16:41 531 查看
看了上一篇:

http://blog.csdn.net/github_33304260/article/details/62891083

我们应该已经可以构建NDK工程了 ,

接下来让我们看看Java调用C代码:

Java调用C代码执行加法操作

java代码:

/**
* 通过JNI简单进行整形加法操作
* @param a
* @param b
* @return
*/
public static native int addInt(int a, int b);


.h代码:

/*
* Class:     com_libin_factory_ndk_NDK
* Method:    addInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_addInt
(JNIEnv *, jclass, jint, jint);


c++代码:

JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_addInt
(JNIEnv *env, jclass type, jint a, jint b) {

return a + b;
}


调用:

Toast.makeText(JNIActivity.this, "相加结果:" + NDK.addInt(10, 2), Toast.LENGTH_SHORT).show();


展示:



说明:

Java_全类名_方法名

Java_com_libin_factory_ndk_NDK_addInt

Java调用C代码执行字符串拼接操作

java代码:

/**
* 通过JNI简单进行字符串拼接操作
* @param s
* @return
*/
public static native String addString(String s);


.h代码:

/*
* Class:     com_libin_factory_ndk_NDK
* Method:    addString
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_libin_factory_ndk_NDK_addString
(JNIEnv *, jclass, jstring);


c++代码:

/**
* 通过JNI简单进行字符串拼接操作
* @param s
* @return
*/
JNIEXPORT jstring JNICALL Java_com_libin_factory_ndk_NDK_addString
(JNIEnv *env, jclass type, jstring s_) {

char *text = jstringToChar(env, s_);

char temp[20] = "    /  I am from c";

strcat(text, temp);

return charToString(env, text);

}


下面两个是工具类

/**
* String转换为Char
* @param env
* @param jstr
* @return
*/
char* jstringToChar(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);

if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}

env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}

/**
* Char转换成String
* @param env
* @param chr
* @return
*/
jstring charToString(JNIEnv *env, const char *chr){
//LOGI("charToString: %s\n", chr);
jclass strClass = env->FindClass("java/lang/String");
jmethodID strConstruct = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(chr));
env->SetByteArrayRegion(bytes, 0, strlen(chr), (jbyte*)chr);
jstring encoding = env->NewStringUTF("utf-8");

return (jstring)env->NewObject(strClass, strConstruct, bytes, encoding);
}


调用:

Toast.makeText(JNIActivity.this, "JNI结果 :" + NDK.addString("I am From Java"), Toast.LENGTH_SHORT).show();


展示:



Java调用C代码执行每个元素加上10

java代码:

/**
* 让C代码给你每个元素加上10
* @param intArray
* @return
*/
public static native int[] increaseArrayEles(int[] intArray);


.h代码:

/*
* Class:     com_libin_factory_ndk_NDK
* Method:    increaseArrayEles
* Signature: ([I)[I
*/
JNIEXPORT jintArray JNICALL Java_com_libin_factory_ndk_NDK_increaseArrayEles
(JNIEnv *, jclass, jintArray);


c++代码:

/**
* 让C代码给你每个元素加上10
* @param intArray
* @return
*/
JNIEXPORT jintArray JNICALL
Java_com_libin_factory_ndk_NDK_increaseArrayEles(JNIEnv *env, jclass type, jintArray intArray_) {
//得到数组的长度
jsize size = env->GetArrayLength(intArray_);
//得到数组元素
jint *array = env->GetIntArrayElements(intArray_, JNI_FALSE); //JNI_FALSE同一份 不开辟新空间
//遍历数组给每个元素加上10
for (int i = 0; i < size; i++) {
*(array + i) += 10;
LOGE("array %d = %d", i, *(array + i));

}
env->ReleaseIntArrayElements(intArray_, array, 0);
//返回结果
return intArray_;

}


调用:

int a[] = {1,2,3,4,5,6,7};
int[] ints = NDK.increaseArrayEles(a);
for (int i = 0 ; i< ints.length;i++){
Logger.e(a[i]+"");
}


展示:



Java调用C代码执行检测密码是否正确

java代码:

/**
* 应用:检测密码是否正确,正确返回200,错误返回400
* @param pwd
* @return
*/
public static native int checkPwd(String pwd);


.h代码:

/*
* Class:     com_libin_factory_ndk_NDK
* Method:    checkPwd
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_libin_factory_ndk_NDK_checkPwd
(JNIEnv *, jclass, jstring);


c++代码:

/**
* 应用:检测密码是否正确,正确返回200,错误返回400
* @param pwd
* @return
*/
JNIEXPORT jint JNICALL
Java_com_libin_factory_ndk_NDK_checkPwd(JNIEnv *env, jclass type, jstring pwd_) {
//假设服务器密码123456
char *otigin = "123456";
char *fromUser = jstringToChar(env, pwd_);
//函数比较字符串是否相同
int code = strcmp(otigin, fromUser);
if (code == 0) {
return 200;
} else {
return 400;
}
}


调用:

Toast.makeText(JNIActivity.this,"密码校验"+ NDK.checkPwd("123456"), Toast.LENGTH_SHORT).show();


展示:



下面我们可以在看看 C调用java:

http://blog.csdn.net/github_33304260/article/details/71213921
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android c语言 jni native java
相关文章推荐