Android NDK中开发中字符串的处理

本文通过一个失败案例展示了在JNI环境中不正确的字符串操作可能导致的问题,并提供了一个修正后的代码示例。通过对错误代码的分析及修正,文章详细解释了如何在JNI中安全地处理字符串,包括如何避免SIGSEGV错误。

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

1、先来个失败案例

  char *src=js;//js是java传递过来的字符串引用
    char *c="I'm from Jnilib";
  size_t length=strlen(src)+strlen(c);
    memcpy(realloc(src,length+1),c,strlen(c));
    *(src+length)='\0';
    return src;

上面代码在触发时候光荣的牺牲了。报的错误是

Fatal signal 11 (SIGSEGV), code 1, fault addr 0xb6df5c in tid 23941

网上的一个正确使用字符串的版本:

    const jchar* c_str= NULL;
    char buff[128] = "hello ";
    char* pBuff = buff + 6;
    /*
     * 在GetStringCritical/RealeaseStringCritical之间是一个关键区。
     * 在这关键区之中,绝对不能呼叫JNI的其他函数和会造成当前线程中断或是会让当前线程等待的任何本地代码,
     * 否则将造成关键区代码执行区间垃圾回收器停止运作,任何触发垃圾回收器的线程也会暂停。
     * 其他触发垃圾回收器的线程不能前进直到当前线程结束而激活垃圾回收器。
     */
    c_str = (*env)->GetStringCritical(env,js,NULL);   // 返回源字符串指针的可能性
    if (c_str == NULL)  // 验证是否因为字符串拷贝内存溢出而返回NULL
    {
        return NULL;
    }
    while(*c_str)
    {
        *pBuff++ = *c_str++;
    }
    (*env)->ReleaseStringCritical(env, js, c_str);
    return (*env)->NewStringUTF(env,buff);

上面错误代码依据正确代码改变后的结果:

 char buffer[128];
    char  *pBuf=buffer;
    //将java字符串转换为C原生字符串

    jboolean  isCopy; // 返回JNI_TRUE表示原字符串的拷贝,返回JNI_FALSE表示返回原字符串的指针
    const jchar *src=(*env)->GetStringCritical(env,js,&isCopy);
    printf("isCopy =%d\n",isCopy);

    //C原生的字符串
    char *c="I'm from Jnilib";
    if (src==NULL)
        return (*env)->NewStringUTF(env,c);
    //java类型字符串转换为C类型字符串后
    printf("javaString: \t%s",src);
    //字符拼接错误
   /* size_t length=strlen(src)+strlen(c);
    memcpy(realloc(src,length+1),c,strlen(c));
    *(src+length)='\0';*/
    //字符拼接
    //size_t  length=strlen(src)+strlen(c);
    //memcpy(realloc(src,length+1), c, strlen(c));
    //*(src+length)='\0';
    printf("compare src+ javaString: %s",src);
    while(*src!='\0'){
        *pBuf++=*src++;
    }
    while(*c!='\0'){
        *pBuf++=*c++;
    }
    *pBuf='\0';
    //释放GetStringChars申请的空间
    (*env)->ReleaseStringCritical(env,js,src);
    free(*c);
    jstring  javaString=(*env)->NewStringUTF(env,buffer);
    return javaString;

参考文献:
http://www.cnblogs.com/lenve/p/4889327.html
http://blog.youkuaiyun.com/sgmenghuo/article/details/44747771
http://blog.youkuaiyun.com/a345017062/article/details/8068917

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值