Android ndk 字符串传参

简介: ndk开发的过程中,Android(Java)与JNI(C/C++)之间,由于参数类型无法互通,所以在传参的过程中,会遇到不少的麻烦。

ndk开发的过程中,Android(Java)与JNI(C/C++)之间,由于参数类型无法互通,所以在传参的过程中,会遇到不少的麻烦。


其中我感觉最麻烦的要数字符串类型的传参



从JAVA传字符串到C++

上层JAVA数据类型String对应NDK为jstring类型,上层传参的方式和普通的java函数间调用并没有什么区别,重点是底层函数,如何将上层传来的jstring转化成本地可认并且可以操作的char *数组


例子如下(函数封装,可由实际函数调用。返回的char *数组一定要在外部记得释放,否则会造成内存泄漏):

char *JavaStringToCStr(JNIEnv *env, jstring str) {
 
    char *result = NULL;
 
    //  先找到JAVA/String类
    jclass strCls = env->FindClass("java/lang/String");
    jstring encodeMothed = env->NewStringUTF("UTF8");
 
    jmethodID java_getBytes = env->GetMethodID(strCls, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray)env->CallObjectMethod(str, java_getBytes, encodeMothed);
    jsize length = env->GetArrayLength(barr);
 
    jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (length > 0) {
        result = (char *)malloc(length + 1);
        memcpy(result, ba, length);
        result[length] = 0;
 
        env->ReleaseByteArrayElements(barr, ba, 0);
    }
 
    return result;
 
}


主题思想:先将String转化成JAVA的字符串数组(对应java描述为byte[]),再对byte进行字符串复制操作。

方法:

    1、定位JAVA的String类

    2、找到String类下面的函数getBytes

    3、调用getBytes将字符串转化成jbyte

    4、进行字符串复制操作

    5、释放相关资源

从C++传字符串到java


        从C++传字符串到java又分为两种形式

        1、通过result返回值的方式

            这种方式其实在使用的时候比较简单,如下即可:

return env->NewStringUTF("jni:string from jni");

        2、通过回调的方式向JAVA传字符串

        这种传值的方式就比较麻烦。回调的方法此处不谈,仅聊参数的传递

        实例如下:

void Java_com_example_ndktest_JniCommon_toJniString(JNIEnv *env, jobject thiz, jstring str) {
 
    char*cStr = JavaStringToCStr(env, str);
 
    constchar *demo = "jni say:";
 
    char*result = (char*)malloc(strlen(demo) +strlen(cStr) + 1);
    memset(result, 0,strlen(demo)+strlen(cStr)+1);
    strcpy(result, demo);
    if(cStr != NULL) {
        strcat(result, cStr);
    }
 
    jstring java_result = env->NewStringUTF(result);
 
    //  调用上层java
    jclass clazz = env->GetObjectClass(thiz);
    jclass cClazz = (jclass)env->NewGlobalRef(clazz);
 
    jmethodID ShowJniString = env->GetMethodID(cClazz,"ShowJniString", "(Ljava/lang/String;)V");
 
    env->CallVoidMethod(thiz, ShowJniString, java_result);
 
    free(cStr);
    free(result);
 
}


重点:其实回调的方式和普通函数的回调类似,重点在于env->GetMethodID这个函数的第三个参数写法。其中括号内代表参数,多个可以直接连续写下去。括号外代表返回值

( arg-types ) ret-type


开发过程中遇到的JAVA类型标识列表

标识 类型 举例
J long -----
Z boolean ----
B byte -----
C char -----
S short -------
I int -----
F float ----
D double ------
Lclassname; specify class Ljava/lang/String;
[type type[] 本文第一段代码:[B
     

目录
相关文章
|
3月前
|
Android开发
Android Stadio Build 窗口字符串乱码问题
在使用Android Studio过程中,如果遇到Build窗口字符串乱码问题,可以通过编辑`studio.vmoptions`文件添加`-Dfile.encoding=UTF-8`配置并重启Android Studio来解决。
168 1
Android Stadio Build 窗口字符串乱码问题
|
1月前
|
编译器 Android开发
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
|
2月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
110 1
|
3月前
|
开发工具 Android开发
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
164 4
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
|
3月前
|
开发工具 Android开发
解决Android Studio编译提示NDK is missing a “platforms“ directory
解决Android Studio编译提示NDK is missing a “platforms“ directory
180 1
|
4月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
【7月更文挑战第28天】在 Android 开发中, NDK 让 Java 与 C++ 混合编程成为可能, 从而提升应用性能。**为何选 NDK?** C++ 在执行效率与内存管理上优于 Java, 特别适合高性能需求场景。**环境搭建** 需 Android Studio 和 NDK, 工具如 CMake。**JNI** 构建 Java-C++ 交互, 通过声明 `native` 方法并在 C++ 中实现。**实战** 示例: 使用 C++ 计算斐波那契数列以提高效率。**总结** 混合编程增强性能, 但增加复杂性, 使用前需谨慎评估。
140 4
|
5月前
|
XML Java Android开发
Android Studio2.2 中支持NDK开发HelloJNI例子
Android Studio2.2 中支持NDK开发HelloJNI例子
31 0
|
6月前
|
Java 开发工具 Android开发
鸿蒙HarmonyOS 与 Android 的NDK有什么区别?
鸿蒙(HarmonyOS)和Android的NDK(Native Development Kit)是两个不同的概念,它们在设计理念、架构、开发方式和目标平台等方面存在着一些显著的不同。
296 0
|
Java Android开发 C++
【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )(二)
【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )(二)
562 0
【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )(二)
|
Android开发
【Android NDK 开发】Android Studio 使用 CMake 导入静态库 ( CMake 简介 | 构建脚本路径配置 | 引入静态库 | 指定静态库路径 | 链接动态库 )(二)
【Android NDK 开发】Android Studio 使用 CMake 导入静态库 ( CMake 简介 | 构建脚本路径配置 | 引入静态库 | 指定静态库路径 | 链接动态库 )(二)
398 0