欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++笔记之【Webservice通讯中文乱码】的那些事

程序员文章站 2022-05-23 07:58:15
C++笔记之【Webservice通讯中文乱码】的那些事。 一、 前言 之前的其他文章中介绍了Webservice的通讯的实现过程,这里再介绍一下通讯过程中的中文乱码怎么处理。...

C++笔记之【Webservice通讯中文乱码】的那些事。

一、 前言

之前的其他文章中介绍了Webservice的通讯的实现过程,这里再介绍一下通讯过程中的中文乱码怎么处理。

二、 中文乱码

出现乱码主要是由于编码的问题造成的,我们在用VS平台编程的时候,大部分使用窄字符,但是Webservice

通讯过程中使用宽字符。

其中,所谓的窄字符,就是用8bit来表示的字符,典型的应用是ASCII码.而宽字符,顾名思义,就是用16bit表示的字符,

典型的有UNICODE.关于windows下的ASCII和UNICODE的更多信息,可以参考这两本经典著作:《windows 程序设计》,

《windows 核心编程》.这两本书关于这两种字符都有比较详细的解说。

【解决方案】:

用文本编辑软件(如:微软的记事本或linux下的vi)创建一个类型转换文件。在该类型转换文件中输入如下一行:

xsd__string = | std::wstring | wchar_t*

保存该文件,为了便于后文的描述,暂且将该文件命名为:mytypemap.dat

用gsoap自带的wsdl2h.exe工具执行如下命令:

wsdl2h.exe -o SoundAlarm.h -t mytypemap.dat https://127.0.0.1:8088/SoundAlarm.wsdl?wsdl

注意:上面的wsdl链接地址和wsdl2h.exe命令是处于一行的,这里写不下,放到两行了。

SoundAlarm.h表示你要根据wsdl文件生成的C++头文件名

之后用gsoap自带的soapcpp2.exe工具执行如下命令:

soapcpp2.exe -C SoundAlarm.h

可以看到生成了客户端用的c++类,观察发现该C++类中的字符串类型现在是wchar_t* 或std::wstring了,进一步测试发现,

中文显示正常了。

还需要进行类型转换:

wstring <--> wchar_t* <--> char* <--> string

转换函数在TypeChange.h中,代码如下:

/*

* @file TypeChange.h

* @brief 【窄字节/符】 与 【宽字节/符】 转换

* @date 2017.04.13

* @author mazheng

*/

#ifndef _TYPE_CHANGE_H_

#define _TYPE_CHANGE_H_

#include

#include

#include

// 使用CString必须使用MFC,并且不可包含

#define _AFXDLL

#include

using namespace std;

//----------------------------------------------------------------------------------

//将 单字节char* 转换为 宽字节 wchar*

inline wchar_t* AnsiToUnicode( const char* szStr )

{

int nLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szStr, -1, NULL, 0 );

if (nLen == 0)

{

return NULL;

}

wchar_t* pResult = new wchar_t[nLen];

MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szStr, -1, pResult, nLen );

return pResult;

}

//----------------------------------------------------------------------------------

// 将 宽字节wchar_t* 转换 单字节char*

inline char* UnicodeToAnsi( const wchar_t* szStr )

{

int nLen = WideCharToMultiByte( CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL );

if (nLen == 0)

{

return NULL;

}

char* pResult = new char[nLen];

WideCharToMultiByte( CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL );

return pResult;

}

//----------------------------------------------------------------------------------

// 将单字符 string 转换为宽字符 wstring

inline void Ascii2WideString( const std::string& szStr, std::wstring& wszStr )

{

int nLength = MultiByteToWideChar( CP_ACP, 0, szStr.c_str(), -1, NULL, NULL );

wszStr.resize(nLength);

LPWSTR lpwszStr = new wchar_t[nLength];

MultiByteToWideChar( CP_ACP, 0, szStr.c_str(), -1, lpwszStr, nLength );

wszStr = lpwszStr;

delete [] lpwszStr;

}

#endif

三、 结束

这里就对中文的乱码的解决方法介绍完了,整个的C++实现Webservice的介绍也快告一段落了,回头再整理一下整个的通讯流程。