Android中Java调用C++代码返回时触发SIGABRT错误的解决咨询
解决JNI调用C++ getCheckSum时的类型转换及参数错误
问题根源
- 参数不匹配:Java侧调用
getCheckSum(A, B)传入两个参数,但JNI实现仅定义了一个jstring参数,导致底层指令解析异常(即你看到的bl、uxtb类型错误)。 - 返回值类型错误:JNI方法声明返回
unsigned short,但在aCStr == NULL时返回NULL(指针类型),与返回值类型不兼容,触发类型转换报错。 - 资源未释放:调用
GetStringUTFChars后未释放资源,会造成内存泄漏。
修复后的完整代码
修正后的JNI实现
//--------------------------------------------------------------------------- // 确保ekmCrcLut已正确定义CRC16查找表 const unsigned short ekmCrcLut[256] = { /* 填入你的CRC16查找表值 */ }; unsigned short ekmCheckCRC16(const unsigned char *dat, unsigned short len) { unsigned short crc = 0xffff; while (len--) { crc = (crc >> 8 ) ^ ekmCrcLut[(crc ^ *dat++) & 0xff]; } crc = (crc << 8 ) | (crc >> 8); crc &= 0x7f7f; return crc; } //--------------------------------------------------------------------------- // 匹配Java侧的双参数方法签名 extern "C" JNIEXPORT jshort JNICALL Java_com_(...)_getCheckSum(JNIEnv *env, jobject thiz, jstring a, jstring b) { // 获取第一个字符串的UTF-8指针 const char *aCStr = env->GetStringUTFChars(a, nullptr); if (!aCStr) { return 0; // 用0代替NULL,符合jshort返回类型 } // 获取第二个字符串的UTF-8指针 const char *bCStr = env->GetStringUTFChars(b, nullptr); if (!bCStr) { env->ReleaseStringUTFChars(a, aCStr); // 释放已获取的资源 return 0; } // 示例:合并两个字符串计算CRC,可根据需求调整逻辑 size_t aLen = strlen(aCStr); size_t bLen = strlen(bCStr); unsigned char *combinedData = new unsigned char[aLen + bLen]; memcpy(combinedData, aCStr, aLen); memcpy(combinedData + aLen, bCStr, bLen); unsigned short crc = ekmCheckCRC16(combinedData, static_cast<unsigned short>(aLen + bLen)); delete[] combinedData; // 释放JNI资源 env->ReleaseStringUTFChars(a, aCStr); env->ReleaseStringUTFChars(b, bCStr); // 转换为JNI标准jshort类型返回 return static_cast<jshort>(crc); }
关键修复说明
- 参数对齐:调整JNI方法参数数量与Java侧一致,解决底层调用的指令解析错误。
- 返回值规范:用
0替代NULL作为异常返回值,确保返回类型与声明匹配。 - 资源管理:调用
ReleaseStringUTFChars释放JNI字符串资源,避免内存泄漏。 - 类型兼容:将C++的
unsigned short转换为JNI标准类型jshort返回,保证跨语言类型适配。
内容的提问来源于stack exchange,提问作者user16458899
相关产品推荐
相关产品推荐

