有些编码转换的文章提到了GSOAP中文乱码的问题,而实际上并不是用那个编码转换的方法解决的。通过抓包,分析原因后,明白GSOAP函数入口为char*的时候,按单字节把中文重新编码了,所以不管是unicode还是gb2312均乱码,必须传wchar_t*才能ok,后来在转的这篇文章中验证了我的想法,并找到了解决办法,因为在此费了不少精神,

一、 问题和分析

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 typemap.dat \ http://xxxxxxxx.asmx?WSDL

从http://xxxxxxx.asmx?WSDL 生成ws.h文件,名空间为ws,使用tyemap.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.

gsoap linux中文乱码,gsoap中文乱码及内存清理等问题的解决方案相关推荐

  1. 网页客户端调用gSoap发布服务,以及中文乱码问题

    gSoap生成的服务器端,用于C++的客户端调用时一般不存在编码问题,只需要程序自动生成的soapXXXProxy.cpp以及SoapXXXProxy.h文件即可. 网页端要调用时,将会遇到很多问题. ...

  2. linux下解压缩文件中文乱码问题的解决

    在windows上压缩的文件,是以系统默认编码中文来压缩文件.由于zip文件中没有声明其编码,所以linux上的unzip一般以默认编码解压,中文文件名会出现乱码. 虽然2005年就有人把这报告为bu ...

  3. oracle11g怎么显示中文,ORACLE11G中PLSQL中文显示乱码、Linux下sqlplus查询中文乱码

    问题描述: 本地是win7操作系统,cmd里面sqlplus进去连接oracle数据库,中文可以正常显示,但是plsql连接oracle数据库,中文显示乱码,还有xshell远程连接oracle服务器 ...

  4. linux中js文件有乱码,解决node.js读取文件时中文乱码问题

    node.js不能很好地支持中文字符,在读取文件的时候,会出现对中文内容读取的乱码问题(linux系统下默认utf-8编码,一般不会出现该问题,但windows和部分虚拟机由于文件存储格式不同,可能会 ...

  5. 问:Linux下Chrome标题栏中文乱码

    From:http://blog.csdn.net/loveaborn/article/details/29579787 在使用Linux的时候你会遇到一些奇奇怪怪的问题,不过,你会在解决这些问题的过 ...

  6. windows下的文本文件在linux下查看,中文显示乱码

    windows下的文本文件在linux下查看,中文显示乱码 伏心救赎 2013-03-05 14:37:37 581 收藏 分类专栏: 基于类linux的开发 </div></div ...

  7. linux连接oracle数据库中文显示乱码

    问题背景: orclae服务的原本就是有也使用正常,win下的pl/sql developer客户端能正常访问且,中文字段也显示正常.unix的aix服务器访问oracle用occi和sqlplus也 ...

  8. 解决linux服务器上matplotlib中文显示乱码问题

    解决linux服务器上matplotlib中文显示乱码问题 参考文章: (1)解决linux服务器上matplotlib中文显示乱码问题 (2)https://www.cnblogs.com/Bell ...

  9. chrome中文方框linux,问:Linux下Chrome标题栏中文乱码

    From:http://blog.csdn.net/loveaborn/article/details/29579787 在使用Linux的时候你会遇到一些奇奇怪怪的问题,不过,你会在解决这些问题的过 ...

  10. Java使用Spire.Pdf或Aspose-Words实现Word转换Pdf在Linux服务器上的中文乱码问题

    一.问题产生的背景 当Word文档中含有中文字符时,不管是使用Spire.Pdf或Aspose-Words实现Word转换Pdf,代码的执行都需要调用操作系统的本地字体库支持,否则所有中文字符都将乱码 ...

最新文章

  1. Guestfish 使用说明
  2. docker安装、源、网络
  3. C++中头文件的命名规则
  4. linux7主机名设置,centos7主机名、网络设置
  5. 我的技术回顾因ABP框架触发DevOps云原生之路-2020年
  6. flash builder4.7 for Mac升级AIRSDK详解
  7. ajax 错误信息error,jquery ajax的error错误信息
  8. 人工智能计算机的相关信息,关于人工智能,计算机领域的尖端(三)
  9. Python字符串isalnum()
  10. Unable to install breakpoint in XXX due to missing line number attributes的解决
  11. 如何安装VMware Workstation虚拟机、及注意事项、安装所需的许可证码
  12. MongoDB概念集合
  13. 对于女生来说,软件测试和前端,学哪一个更好啊
  14. Java中的正则表达式 regex
  15. 室内定位程序_如何设计室内AR导航系统?
  16. 复古决战快速施法穿墙秒怪分析流程及安全防护
  17. Iass、Pass、Sass三种云服务有什么区别
  18. SpringBoot基于websocket的网页聊天
  19. 台式win7f1到f12热键取消_Windows 7旗舰版系统中键盘F1到F12快捷键的作用详解
  20. Ubuntu synaptic install

热门文章

  1. PPT:WMS仓储系统解决方案
  2. 通过ipsw控制固定端口的网速
  3. 50. 文件上传篇——文件上传漏洞原理
  4. 供应链金融你了解多少?
  5. CentOS 7.3安装详解
  6. android最早的版本,光遇最早版本
  7. OpenCV+Python车牌字符分割和识别入门 (含新能源车牌识别)
  8. 使用CNN进行情感分析(Sentiment Analysis)
  9. 程序员的奋斗史(七)——沟通交流、表达能力的重要性
  10. FILecoin 将重大战略升级,FIL 或将引导商业数据