1.下载相关组件最新版本2.8.14 http://www.cr173.com/soft/58102.html ,解压缩到F盘根目录下面。
2.下载之后通过控制台程序来生成对应webservice的相关文件,能够大大节省我们自己构造soap消息的时间,因为webservice发布的方法的参数复杂结构会严重影响
如上两步之后 F:\gsoap-2.8\gsoap\bin\win32 下面会生成很多文件,其中包括webservice接口参数的结构类,以及全部接口信息等
3.创建MFC应用程序
4.拷贝F:\gsoap-2.8\gsoap\bin\win32 下面的 soapH.h soapStub.h soapC.cpp soapClient.cpp MobileServiceSoapBinding.nsmap
以及F:\gsoap-2.8\gsoap 下面的stdsoap2.h stdsoap2.cpp
将上述7个文件拷贝到新建MFC应用程序的include目录下面留待备用
5.将上述6个文件(除MobileServiceSoapBinding.nsmap之外),引用到MFC项目中,将soapC.cpp soapClient.cpp stdsoap2.cpp 的属性中的“使用预编译头”改为“不使用”
6. 在MFC应用程序对应的访问文件中增加如下代码:
#include "soapH.h"
#include "MobileServiceSoapBinding.nsmap"
如下是访问实现源码:
struct soap _local_soap;
soap_init(&_local_soap);
soap_set_mode(&_local_soap, SOAP_C_UTFSTRING);//setlocale(LC_ALL, "");//设置程序locale为系统默认
_ns1__userLoginReq _req;
_req.Account = "XXXX" ;
_req.Password = "XXXX" ;
_req.Version = "XXXX";
_ns1__userLoginRes _res;
soap_call___ns1__userLogin(&_local_soap,"webservise_URL","",&_req,&_res);
std::vector
_iter = _res.DeviceAll->Device.begin();
std::string str;
str =(*_iter)->Name;
char dststr[100];
Utf8ToGb2312(dststr,100 ,str.data(),str.length());
7.到此,访问方法结束。
如下是关于GSOAP的一些知识扩充
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*,
道理上,在转换到当前字符集,应该不会乱码。
中文乱码与locale有关,这里给出两种解决方法:
一、设置locale
1、setlocale(LC_ALL, "");//设置程序locale为系统默认(我的系统是zh_CN.utf8),gsoap内部进行编码转换依赖于locale,所以必须设置为中文环境。
2、gSoap初始化 gSoap生成的代理类名字为:CSmsProxy
CSmsProxy soapRequest(SOAP_C_MBSTRING);
下面同一般编程。gSoap会自动把字符串转换为正确的编码。
二、不设置locale,使用默认的"C" locale,程序中传给gSoap、从gSoap接收的字符串都使用utf8编码
代理类初始化: CSmsProxy soapRequest(SOAP_C_UTFSTRING);
下面同一般编程。gSoap会把字符串当成utf8编码处理。
下面附带gb2312与utf8编码之间的转换函数:
#define u32 unsinged int
//gb2312转utf8
void Gb2312ToUtf8(char* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen)
{
#ifdef WIN32
int i = MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, NULL, 0);
wchar_t * strSrc = new wchar_t[i+1];
MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, strSrc, i);
i = WideCharToMultiByte(CP_UTF8, 0, strSrc, -1, NULL, 0, NULL, NULL);
if (i >= dwOutLen)
{
i = dwOutLen - 1;
}
WideCharToMultiByte(CP_UTF8, 0, strSrc, -1, pstrOut, i, NULL, NULL);
delete strSrc;
#else
iconv_t iConv = iconv_open("utf-8", "gb2312");
iconv(iConv, (char **)&pstrIn, (size_t *)&dwInLen, (char **)&pstrOut, (size_t *)&dwOutLen);
iconv_close(iConv);
#endif
}
//utf8转gb2312
void Utf8ToGb2312(char* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen)
{
if (NULL == pstrOut)
{
return ;
}
#ifdef WIN32
int i = MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, NULL, 0);
wchar_t * strSrc = new wchar_t[i+1];
MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, strSrc, i);
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
if (i >= dwOutLen)
{
i = dwOutLen - 1;
}
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, pstrOut, i, NULL, NULL);
delete strSrc;
#else
iconv_t iConv = iconv_open("gb2312", "utf-8");
iconv(iConv, (char **)&pstrIn, (size_t *)&dwInLen, (char **)&pstrOut, (size_t *)&dwOutLen);
iconv_close(iConv);
#endif
}