Android jni 在C++代码中给HashMap<Integer, ArrayList<String>>类型的参数赋值

这篇博客详细记录了如何在C++中使用JNI技术向HashMap<Integer, ArrayList<myStruct>>插入数据的过程,包括对Java对象的创建、方法调用等步骤。同时,还介绍了如何通过StringBuffer实现Java中String类型的引用传递,以便在C++中进行修改和赋值操作。示例代码清晰展示了整个流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目中有部分需求需要给Android端实现部分功能,以jni方式实现,对此方式不是很熟悉,浅浅地记录一下 当参数类型为HashMap<Integer, ArrayList>时,该如何在C++中向此容器插入数据的问题.
代码片段如下

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myProject_XXNative_myFun(JNIEnv *env, jclass clazz, jobject desMap)
{
	//...
	std::map<int, std::vector<myStruct>> srcMap;
	std::map<int, std::vector<myStruct>>::iterator iter = srcMap.begin();
    for(; iter != srcMap.end(); iter++)
    {
        int nKey = iter->first;
        jclass integerClass = env->FindClass("java/lang/Integer");
        jmethodID integerConstructorID = env->GetMethodID(integerClass, "<init>", "(I)V");
        jobject key = env->NewObject(integerClass, integerConstructorID, nKey);
        std::vector<myStruct> srcVec = iter->second;
        int nSize = srcVec.size();
        jclass mapClass = env->FindClass("java/util/HashMap");
        jmethodID putMethodID =
                env->GetMethodID(
                        mapClass,
                        "put",
                        "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;" );

        jclass arrayListClass = env->FindClass("java/util/ArrayList");
        jmethodID arrayListInit = env->GetMethodID(arrayListClass, "<init>", "()V");
        jmethodID addToList = env->GetMethodID(
                arrayListClass,
                "add",
                "(Ljava/lang/Object;)Z" );
        jobject listObj = env->NewObject(arrayListClass, arrayListInit);
        for(int i = 0; i < nPaperSize; i++)
        {
            myStruct tObj = srcVec.at(i);
            jstring firstStr = str2jstring(env, tObj.firstStr.c_str());
            jstring secondStr = str2jstring(env, tObj.secondStr.c_str());
            env->CallBooleanMethod(listObj, addToList, firstStr);
            env->CallBooleanMethod(listObj, addToList, secondStr);
            env->DeleteLocalRef(firstStr);
            env->DeleteLocalRef(secondStr);
        }
        env->CallObjectMethod(papers_map, putMethodID, key, listObj);
        //资源释放
        env->DeleteLocalRef(integerClass);
        env->DeleteLocalRef(key);
        env->DeleteLocalRef(mapClass);
        env->DeleteLocalRef(arrayListClass);
        env->DeleteLocalRef(listObj);
    }
}

顺便一提,如果参数中想以引用传递方式传java中的String类型(传到C++方法中修改赋值),可以用StringBuffer实现
代码片段如下

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myProject_XXNative_myFun(JNIEnv *env, jclass clazz, jobject str_id)
{
	std::string strId;
    jstring jstrId = env->NewStringUTF(strId.c_str());
    jclass stringBufferClass = env->FindClass("java/lang/StringBuffer");
    jmethodID appendMethodID =
            env->GetMethodID(
                    stringBufferClass,
                    "append",
                    "(Ljava/lang/Object;)Ljava/lang/StringBuffer;" );
    env->CallObjectMethod(str_id, appendMethodID, jstrId);
    //资源释放
    env->DeleteLocalRef(jstrId);
    env->DeleteLocalRef(stringBufferClass);
}
可以通过以下步骤将 C++ 中的 `vector<string>` 数据传递到 Java 中的 `String[]` 数组中: 1. 编写 JNI 接口方法,接收 `vector<string>` 数据,并将其转换为 `jobjectArray` 对象: ```c++ JNIEXPORT jobjectArray JNICALL Java_com_example_MyClass_getStringArray(JNIEnv *env, jobject obj, jobject stringVector) { jclass stringClass = env->FindClass("java/lang/String"); jmethodID stringConstructor = env->GetMethodID(stringClass, "<init>", "([BLjava/lang/String;)V"); std::vector<std::string> strVector; getVectorData(stringVector, strVector); jobjectArray stringArray = env->NewObjectArray(strVector.size(), stringClass, NULL); for (int i = 0; i < strVector.size(); i++) { jbyteArray bytes = env->NewByteArray(strVector[i].size()); env->SetByteArrayRegion(bytes, 0, strVector[i].size(), (jbyte*)strVector[i].data()); jstring encoding = env->NewStringUTF("UTF-8"); jobject stringObj = env->NewObject(stringClass, stringConstructor, bytes, encoding); env->SetObjectArrayElement(stringArray, i, stringObj); env->DeleteLocalRef(stringObj); env->DeleteLocalRef(encoding); env->DeleteLocalRef(bytes); } return stringArray; } ``` 其中,`getVectorData()` 是一个自定义的函数,用于从 `jobject` 对象中获取 `vector<string>` 数据。 2. 在 Java 代码中调用 JNI 接口方法,获取 `String[]` 数组: ```java public class MyClass { static { System.loadLibrary("myLibrary"); } public static native String[] getStringArray(Vector<String> stringVector); public static void main(String[] args) { Vector<String> stringVector = new Vector<>(); stringVector.add("Hello"); stringVector.add("world"); stringVector.add("!"); String[] stringArray = getStringArray(stringVector); for (String str : stringArray) { System.out.println(str); } } } ``` 在 Java 代码中,首先需要加载 C++ 的动态库,然后调用 JNI 接口方法 `getStringArray()`,将 `Vector<String>` 数据传递给 C++,并获取转换后的 `String[]` 数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值