码迷,mamicode.com
首页 > 其他好文 > 详细

jni 字符串的梳理 2 字符串的处理操作

时间:2017-06-22 18:40:36      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:释放   类型   ssl   android   native   ++   越界   c++   efi   

我们实现下面的一个功能:

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分配足够的空间来存储新的字符串。

在使用指针时,需要时刻注意空间的分配,空间的大小,空间的释放等问题

 

jni 字符串的梳理 2 字符串的处理操作

标签:释放   类型   ssl   android   native   ++   越界   c++   efi   

原文地址:http://www.cnblogs.com/kebibuluan/p/7066296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!