jni 字符串的梳理 2 字符串的处理操作
我们实现下面的一个功能:
1、首先在java层传递一个字符串到c层,c层首先将jstring转换成char*类型,然后将两个字符串相加,然后再再将char*类型转换成jstring,在上层显示出来
我们来看底层程序的代码:
// // Created by wei.yuan on 2017/6/13. // #include <jni.h> #include <string.h> #include <pthread.h> #include "im_weiyuan_com_jni_Sdk.h" #include "im_weiyuan_com_jni_Sdk_OnSubProgressListener.h" #include "im_weiyuan_com_jni_Sdk_SdkHodler.h" JavaVM *g_VM; jobject g_obj; #include <jni.h> #include <string.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dlfcn.h> #include <assert.h> #include <android\log.h> #include <errno.h> #include <pthread.h> #include <android/log.h> #define LOG_TAG "Native" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) /*方法三,调用C库函数,*/ char* join(char *s1, char *s2) { char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator //in real code you would check for errors in malloc here if (result == NULL) exit (1); strcpy(result, s1); strcat(result, s2); return result; } /*1、第一步将输入的jstring类型转换成char*类型 * 2、将两个char*类型的字符串拼接起来 * 3、将cha*类型的转换成jstring类型,返回给java层 * * * * */ JNIEXPORT jstring JNICALL Java_im_weiyuan_com_jni_Sdk_getStringFromC (JNIEnv * env, jobject jobj, jstring jstr){ const jbyte *str; str = (*env)->GetStringUTFChars(env, jstr, NULL); if (str == NULL) { return NULL; /* OutOfMemoryError already thrown */ } LOGE("123456789:%s\n",str); char *hello = "I from C++"; char*result = NULL; result = join(str,hello); LOGE("123456789 result len is :%d\n",strlen(result)); (*env)->ReleaseStringUTFChars(env, jstr, str); //malloc申请的内存记得要是否 if(result !=NULL){ LOGE("123456789 result len is free\n"); free(result); } return (*env)->NewStringUTF(env, result); }
这里一定要注意strcat和strcpy的使用方式:
上面的代码还有一个致命的问题:
要为所需的内存分配足够的空间,否则会出现严重的错误。同时,分配的时候若想使用strlen()来确定内存大小时,要注意进行转换,因为内存中是以字节数来计算大小的,而strlen返回的只是字符串长度,如strlen("abc")返回的3,但是可能每个字符占两字节(不同系统有所不同),即内存大小应该为6。
所以上面的代码应该写成下面的形式:
/*方法三,调用C库函数,*/ char* join(char *s1, char *s2) { char *result = malloc((strlen(s1)+strlen(s2)+1)* sizeof(char));//+1 for the zero-terminator //in real code you would check for errors in malloc here if (result == NULL) exit (1); strcpy(result, s1); strcat(result, s2); return result; }
头文件:#include <string.h> strcat() 函数用来连接字符串,其原型为: char *strcat(char *dest, const char *src); 【参数】dest 为目的字符串指针,src 为源字符串指针。 strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。 注意:dest 与 src 所指的内存空间不能重叠,且 dest 要有足够的空间来容纳要复制的字符串。 【返回值】返回dest 字符串起始地址。 【实例】连接字符串并输出。
#include <stdio.h> #include <string.h> int main () { char str[80]; strcpy (str,"these "); strcat (str,"strings "); strcat (str,"are "); strcat (str,"concatenated."); puts (str); return 0; }
错误案例一:
在实际开放中,我们可能会用到strcat拼接两个字符串,例如 char a[6] = "hello"; char b[6] = "world"; strcat(a,b); free(a); free(b); 此时会出现越界情况,由于a只有6个字符的空间,拼接后超出了本身空间大小,因此会报错, 所以需要用realloc重新给a分配足够的空间来存储新的字符串。 在使用指针时,需要时刻注意空间的分配,空间的大小,空间的释放等问题
头文件:#include <string.h>
定义函数:char *strcpy(char *dest, const char *src);
函数说明:strcpy()会将参数src 字符串拷贝至参数dest 所指的地址。
返回值:返回参数dest 的字符串起始地址。
附加说明:如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strncpy()来取代。
视频中:
该方法是错误的使用strcat也会出现错误,因为fromJava也没有足够的空间
posted on 2017-06-22 17:40 luzhouxiaoshuai 阅读(868) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!