gsoap中文乱码及内存清理等问题的解决方案

简介: gsoap中文乱码的问题 -- 拔剑,2010-08-31 一、 问题和分析 gsoap在调用Webservice过程中,如果字符串中有汉字,很容易出现乱码。
gsoap中文乱码的问题

 -- 拔剑,2010-08-31

 

一、 问题和分析

 

gsoap在调用Webservice过程中,如果字符串中有汉字,很容易出现乱码。 由于网络间一般用UTF8表示

字串(ANSI字串- (char < 128)本身已经符合UTF8编码规则),所以ANSI字符不会乱码,而一个汉字

的传统表示需要两个字符,而在wchar_t宽字符串中只需一个字符表示。

 

一个汉字用UTF8表示通常占用3个BYTE, 如:

         你  --〉0xe4, 0xbd, 0xa0

         好  --> 0xe5, 0xbd, 0x21

 

gSoap在封装XML包时,在进行utf8字符转换时:

   1)如果入口参数为 char* / std::string (即用多字节表示汉字)时,

      汉字因为已经用2个字节(窄字符)表示,此时的UTF8编码已近不是对该汉字的码值编码,

      而是对组成该汉字的两个字符进行utf8编码,结果自然不对了。因此乱码。

                    UTF8(0xAABB)   !=  UTF8(0XAA + 0XBB)

   2)如果入口参数为 wchar_t* / std:wstring(即一个汉字用一个字符表示)时,

      汉字因为用1个宽字符表示(两个字节),因此UTF8转换没有问题。

 

gSoap在解包时,因为来源字符串已经用UTF8表示,因此在gsoap的response中,用std::string/char*,

道理上,在转换到当前字符集,应该不会乱码。

 

二、解决方案

 

   很简单,在gsoap的数据类型中,用wchar_t* 或std::wstring代替std:string/char*.同时,

为了确保Proxy类用UTF8编解码,可以在其构造函数中强行赋编码方式,如:   

          MyServiceSoapProxy gs(SOAP_C_UTFSTRING); 

 

由于gsoap的调用代码是自动生成的,如何办?

   我们需要在生成gSoap调用代码时,强制使用wchar_t*/std::wstring. 我们可以修改default类型转换

文件或者强制使用某个类型转换文件。如:

gSOAP两大工具的用法从WSDL中产生头文件,用法:
    wsdl2h -o 头文件名 WSDL文件名或URL
    wsdl2h常用选项
    -o 文件名,指定输出头文件
    -n 名空间前缀 代替默认的ns
    -c 产生纯C代码,否则是C++代码
    -s 不要使用STL代码
    -t 文件名,指定type map文件,默认为typemap.dat
    -e 禁止为enum成员加上名空间前缀
 type map文件用于指定SOAP/XML中的类型与C/C++之间的转换规则,比如在mytypema.dat(拷贝自default typemap.dat)里写
    xsd__string = | std::wstring | wchar_t*    # 注释符号为#
 那么SOAP/XML中的string将转换成std::wstring或wchar_t*,这样能更好地支持中文。

 例:

    wsdl2h -o ws.h  -n ws -t mytypemap.dat \ http://www.aaa.com/Service.asmx?WSDL
    从http://www.aaa.com/Service.asmx?WSDL 生成ws.h文件,名空间为ws,使用mytyemap.dat指定的转换规则。

 

三、一点说明

  1)入口参数,用局部变量的地址付给参数,避免内存分配销毁

  2)gSoap will use soap_malloc(..) to allocate memory, which is different from malloc()/new

     you should NOT delete memory allocated by gsoap by yourself in Response Object.

 

        GSOAP CAN AUTOMATICALLY DELETE THOSE MEMORIES IT ALLOCATED!!!!!!

 

     If you tried to delete those memory allocated by gSOAP, memory leak could appear.

     (Maybe to use soap_delete(soap*, pointer) is safe, not fully tested, and no need!)

  3)不支持__int64 (如表示时间)

     simple, directly comments out conditional macro covering

              gsoap_s2LONG64(...)

              gsoap_LONG642s(...)

     like:

             //#ifndef XXXX

             //#endif

  4) __int64转换失败问题(时间是用__int64表示的)

     In windows, use "%I64d" instead of "%lld".

  5)同时调用多个Web service接口

     自需要把Web service的WSDL文件放在一起给wsdl2h调用,如:

         wsdl2h -o ws.h -n ws -t mytypemap.dat WSDL_file1 WSDL_File2 .... WSDL_FileN

     生成的文件中,ENDPOINT被写在一个字串里面,因此需要修改生成的源代码

        const char* ENDPOINT ="http_url1  http_url2 http_url3 .. http_urlN";

     ===>

        contst char* END_POINT_IF1 = "http_url1";

        const  char* END_PINT_IF2 = "http_url2" ;

       ...

        const char* END_POIINT_IFN = "http_urlN";

    ==> 同时修改每个Webservice调用的Endpoint值,用END_POINT_IF1,....END_POINT_IFN分别替代。

 7) you can use soap_malloc(..) to create temp memory, and soap will automatically delete

    such kind of data in Proxy destructor.

 

    If you want to delete the memory by yourself, or even after soap object (Proxy) is destructed.

    You  can use

                         soap_unlink(...)

    to de-reference this allcocated memory and later use

                         free(...)

    to release the memory by yourself.

  8) Do not copy Soap PROXY instance, otherwise could cause memory issue. You can use pointer,

     or reference type to pass such parameters.

  9)二进制流的传输

     XML利用Base64编码的文本传输二进制流,WebService/gSoap支持无限制长度的二进制流传输。

     在gsoap中要传输二进制流不需要做特别的处理,gsoap会自动将数据进行Base64编解码。

 

 

四、调试

  1)察看gsoap的XML封包可以在下面的函数设置断点:

            gsoap_fsend/fsend

            gsaop_frecev/frecv

  2)数据类型转换

            gsoap_s2LONG64

            gsoap_s2int

            ...

            gsoap_LONG642s

            ...

   3) turn on

            SOAP_DEBUG

      to see more thing.

 

参考:

  http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc7.2.3

  http://panxq0809.javaeye.com/blog/709173

  (其余忘记了)

目录
相关文章
|
运维 监控 Java
内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
全网最全的内存溢出CPU占用过高排查文章,包含:问题出现现象+临时解决方案+复现问题+定位问题发生原因+优化代码+优化后进行压测,上线+复盘
2196 5
|
2月前
|
Web App开发 缓存 JavaScript
技术分享:深入探索内存泄漏——识别、分类与解决方案
【8月更文挑战第27天】在软件开发的浩瀚星海中,内存管理始终是程序员们必须面对的重要课题。内存泄漏,作为内存管理不善的典型症状,不仅影响应用性能,还可能导致系统崩溃,是每位开发者都需警惕的“暗礁”。本文将带您深入探索内存泄漏的本质、常见类型及有效的解决策略,助力您的工作学习之旅更加顺畅。
43 0
|
4月前
|
存储 缓存 NoSQL
Redis是一种高性能的内存数据库,常用于高并发环境下的缓存解决方案
【6月更文挑战第18天】**Redis摘要:** 高性能内存数据库,擅长高并发缓存。数据存内存,访问迅速;支持字符串、列表等多元数据类型;具备持久化防止数据丢失;丰富命令集便于操作;通过节点集群实现数据分片与负载均衡,增强可用性和扩展性。理想的缓存解决方案。
56 1
|
3月前
|
设计模式 安全 Java
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
80 0
|
3月前
|
监控
LabVIEW程序内存泄漏分析与解决方案
LabVIEW程序内存泄漏分析与解决方案
113 0
|
5月前
|
Java
Handler内存泄漏原因及解决方案
Handler内存泄漏原因及解决方案
53 0
|
5月前
|
存储 监控 Java
JVM内存泄漏的分析与解决方案
JVM内存泄漏的分析与解决方案
112 2
|
5月前
|
存储 缓存 监控
Linux系统内存下降:原因、诊断与解决方案
Linux系统内存下降:原因、诊断与解决方案
147 0
|
11月前
|
Arthas Java 测试技术
微服务轮子项目(49) -常见JVM内存错误及解决方案
微服务轮子项目(49) -常见JVM内存错误及解决方案
105 0
|
11月前
|
存储 数据库 C语言
Hawkeyes: x86软件迁移Arm的弱内存序问题解决方案
本文介绍了x86软件迁移到Arm过程中可能遇到的弱内存序问题的解决方案,解析了弱内存序问题的根因,介绍了Hawkeyes的架构和实现原理。欢迎有需求的团队发送邮件咨询
1128 0