GSOAP 使用方法

1.下载相关组件最新版本2.8.14     http://www.cr173.com/soft/58102.html  ,解压缩到F盘根目录下面。

2.下载之后通过控制台程序来生成对应webservice的相关文件,能够大大节省我们自己构造soap消息的时间,因为webservice发布的方法的参数复杂结构会严重影响

    a. 


     b.

  

  如上两步之后 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  的属性中的“使用预编译头”改为“不使用”

  GSOAP 使用方法_第1张图片

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::iterator _iter;
_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 
}

//gb2312转Unicode 
void Gb2312ToUnicode(wchar_t* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    u32 i = MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, NULL, 0); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    MultiByteToWideChar(CP_ACP, 0, pstrIn, -1, pstrOut, i); 
#else 
    iconv_t iConv = iconv_open("unicode", "gb2312"); 
    iconv(iConv, (char**)pstrIn, &dwInLen, (char**)pstrOut, &dwOutLen); 
    iconv_close(iConv); 
#endif 
} 

//Unicode转Gb2312 
void UnicodeToGb2312(char* pstrOut, u32 dwOutLen, const wchar_t* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    u32 i = WideCharToMultiByte(CP_ACP, 0, pstrIn, -1, NULL, 0, NULL, NULL); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    WideCharToMultiByte(CP_ACP, 0, pstrIn, -1, pstrOut, i, 0, 0); 
#else 
    iconv_t iConv = iconv_open("gb2312", "unicode"); 
    iconv(iConv, (char**)pstrIn, &dwInLen, (char**)pstrOut, &dwOutLen); 
    iconv_close(iConv); 
#endif 
} 

//utf8转Unicode 
void Utf8ToUnicode(wchar_t* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen) 
{ 
    if (NULL == pstrOut) 
    { 
        return ; 
    } 
#ifdef WIN32 
    u32 i = MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, NULL, 0); 
    if (i >= dwOutLen) 
    { 
        i = dwOutLen - 1; 
    } 
    MultiByteToWideChar(CP_UTF8, 0, pstrIn, -1, pstrOut, i); 
#else 
    iconv_t iConv = iconv_open("unicode", "utf-8"); 
    iconv(iConv, (char**)pstrIn, &dwInLen, (char**)pstrOut, &dwOutLen); 
    iconv_close(iConv); 
#endif 
}


你可能感兴趣的:(网络,C++)