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 for the zero-terminator
//in real code you would check for errors in malloc here
if (result == NULL) exit (); 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)+)* sizeof(char));//+1 for the zero-terminator
//in real code you would check for errors in malloc here
if (result == NULL) exit (); 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[];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return ;
}
错误案例一:
在实际开放中,我们可能会用到strcat拼接两个字符串,例如 char a[] = "hello";
char b[] = "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也没有足够的空间
jni 字符串的梳理 2 字符串的处理操作的更多相关文章
- Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法
首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的: 第一种方法: jobject NewObject(jclass clazz , jmethodI ...
- JS字符串替换函数:Replace(“字符串1″, “字符串2″),
JS字符串替换函数:Replace(“字符串1″, “字符串2″), 1.我们都知道JS中字符串替换函数是Replace(“字符串1″, “字符串2″),但是这个函数只能将第一次出现的字符串1替换掉, ...
- C#算法之判断一个字符串是否是对称字符串
记得曾经一次面试时,面试官给我电脑,让我现场写个算法,判断一个字符串是不是对称字符串.我当时用了几分钟写了一个很简单的代码. 这里说的对称字符串是指字符串的左边和右边字符顺序相反,如"abb ...
- 将数据转化成字符串时:用字符串的链接 还是 StringBuilder
/* 目的:将数据转化成字符串时:用字符串的链接 还是 StringBuilder呢? */ public class Test{ public static void main(String[] a ...
- C风格字符串与C++风格字符串
C风格字符串与C++风格字符串 C风格字符串:对字符串进行操作的 C 函数定义在头文件<cstring>中: 1. 字符串定义:char* result: 2. 字符串的最后一个字符是nu ...
- 【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...
37.(字符串)有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环, ...
- loadrunner通过字符串左右边界切割字符串
void web_reg_save_param_custom(char *sourceStr, char* outpuStr, char *leftBdry, char *rightBdry){ ...
- Swift3.0语言教程使用字符串创建和初始化字符串
Swift3.0语言教程使用字符串创建和初始化字符串 Swift3.0语言教程使用字符串创建和初始化字符串,在编程语言中,字面值是很常见的数据描述形式.人们可以通过字面所表达的意思,获知其含义,尤其是 ...
- Qt字符串类——2. 查询字符串数据
(1)函数QString::startsWith()判断一个字符串是否以某个字符串开头.此函数具有两个参数,第一个参数指定了一个字符串,第二个参数指定是否大小写敏感(默认情况下,是大小写敏感的),例如 ...
随机推荐
- Pytorch分类和准确性评估--基于FashionMNIST数据集
最近在学习Pytorch v1.3最新版和Tensorflow2.0. 我学习Pytorch的主要途径:莫烦Python和Pytorch 1.3官方文档 ,Pytorch v1.3跟之前的Pytorc ...
- 公有继承中派生类Student对基类Person成员的访问 代码参考
#include <iostream> #include <cstring> using namespace std; class Person { private: char ...
- CSS用户自定义样式
在浏览器中打开前面写的例子页面,你会发现 <strong> 元素中的文字会比其他文字粗一些.这些样式就是在浏览器定义的默认HTML样式. 而<strong> 元素是红色的,这是 ...
- Linux (八)服务
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.服务的概念 操作系统中在后台持续运行的程序,本身并没有操作界面,需要通过端口号访问和操作.CentO ...
- ASP.NET MVC 数据传递 视图向控制器传递
视图向控制器传递 MVC 视图向控制器传递,就是获取用户输入的数据,在去进行操作 好了,我们不多说直接进行我们的案例. 在HomeController类中添加下来方法 [HttpPost] publi ...
- Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
在数列 a_1, a_2, -, a_n中,定义两个元素 a_i 和 a_j 的距离为 |i-j|+|a_i-a_j|,即元素下标的距离加上元素值的差的绝对值,其中 |x| 表示 x 的绝对值. 给定 ...
- Java实现 LeetCode 617 合并二叉树(遍历树)
617. 合并二叉树 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点 ...
- Java实现 LeetCode 593 有效的正方形(判断正方形)
593. 有效的正方形 给定二维空间中四点的坐标,返回四点是否可以构造一个正方形. 一个点的坐标(x,y)由一个有两个整数的整数数组表示. 示例: 输入: p1 = [0,0], p2 = [1,1] ...
- Java实现 蓝桥杯VIP 算法训练 传球游戏
[问题描述] 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每 ...
- Java实现 LeetCode 92 反转链表 II
92. 反转链表 II 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5-> ...