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