zoukankan      html  css  js  c++  java
  • 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 <androidlog.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
    ",str);
        char *hello = "I from C++";
    
        char*result = NULL;
        result = join(str,hello);
    
        LOGE("123456789 result len is :%d
    ",strlen(result));
        (*env)->ReleaseStringUTFChars(env, jstr, str);
        //malloc申请的内存记得要是否
        if(result !=NULL){
            LOGE("123456789 result len is free
    ");
            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也没有足够的空间

  • 相关阅读:
    中产阶级_百度百科
    第二天--设置一个数据模型
    请大家支持珊瑚虫~~请大家帮帮soff~~
    Linux Socket学习(十二)
    Debian下调整时间
    Emacs 牵手 scim
    Linux Socket学习(十三)
    mplayer解码
    创建第一个Symfony工程
    页面的基本创建
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7066296.html
Copyright © 2011-2022 走看看