C++調用WebService

1. gSOAP是一個開源的項目,用它能夠方便的使用c/c++地進行SOAP客戶端和服務器端編程,而沒必要了解xml和SOAP協議的細節java

wsdl2h.exe: 編譯wsdl文件生成c/c++頭文件c++

-o 文件名,指定輸出頭文件 
-n 名空間前綴 代替默認的ns 
-c 產生純C代碼,不然是C++代碼 
-s 不要使用STL代碼 
-t 文件名,指定type map文件,默認爲typemap.dat 
-e 禁止爲enum成員加上名空間前綴git

soapcpp2.exe: gSOAP編譯器,編譯頭文件生成服務器和客戶端都須要的c/c++文件(默認使用STL,須要stlvector.h)web

-C 僅生成客戶端代碼 
-S 僅生成服務器端代碼 
-L 不要產生soapClientLib.c和soapServerLib.c文件 
-c 產生純C代碼,不然是C++代碼(與頭文件有關) 
-I 指定import路徑(見上文) 
-x 不要產生XML示例文件 
-i 生成C++包裝,客戶端爲xxxxProxy.h(.cpp),服務器端爲xxxxService.h(.cpp)編程

2. 生成存客戶端存根程序和框架
wsdl2h -o xx.h http://192.168.40.8:88/GMM?wsdl 服務器

或者 wsdl2h -o xx.h http://js.gps163.com:8994/Server/CsService.svc?wsdl
soapcpp2 -C -L -x -i xx.h (soapcpp2 xx.h -C -I D:\gsoap-2.7\gsoap\import)框架

3. 把以下生成的文件添加到項目:
soapStub.h,soapH.h,stdsoap2.h編輯器

soapC.cpp,soapClient.cpp,stdsoap2.cpp編碼

soapBasicHttpBinding_USCOREIGMMProxy.cppspa

soapBasicHttpBinding_USCOREIGMMProxy.cpp

BasicHttpBinding_USCOREIGMM.nsmap

wsock32.lib

4. 調用

#include "soapBasicHttpBinding_USCOREIGMMProxy.h"
#include "BasicHttpBinding_USCOREIGMM.nsmap"

//代理方式調用不須要初始化
//struct soap xxSoap;
//soap_init(&xxSoap);

//代理類對象
xxWebServiceSoap xxProxy; 

//設置頭信息
//SOAP_ENV__Header envHeader;
//xxProxy.soap->header = &envHeader;

//web服務對象
_ns1__xx xx; 

//web服務結果對象 
_ns1__xxResponse xxResponse;

//調用WebService方法


5. 使用的例子:

 1 CString CGetLocation::GetLocation(int iLon, int iLat)
 2 {
 3     CString strAddress = _T("");
 4 
 5     struct soap soap1 ;
 6     soap_init(&soap1);
 7     soap_set_mode(&soap1, SOAP_C_MBSTRING);
 8 
 9     BasicHttpBinding_USCOREIGMMProxy locationService(soap1);
10 
11     _ns3__GetLocation    getLocation;
12     _ns3__GetLocationResponse getLocationRes;
13 
14     bool blOffset = false;
15     getLocation.Latitude = &iLat;
16     getLocation.Longitude = &iLon;
17     getLocation.blOffset = &blOffset;
18 
19     int nOK = -1;
20 
21     try
22     {
23         nOK = locationService.GetLocation(strWCFUrl.c_str(), NULL, &getLocation, &getLocationRes);
24     }
25     catch (...)
26     {
27         CString strLog;
28         strLog.Format(_T("GetLocation try catch error : %d\r\n"), GetLastError());
29         TRACE(strLog);
30         return strAddress;
31     }
32 
33 
34     if (nOK != SOAP_OK)
35     {
36         char szError[255] = {0};
37         soap_sprint_fault(&soap1, szError, 255);
38 
39         CString strLog;
40         strLog.Format(_T("SOAP Error: %s\r\n"), szError);
41         TRACE(strLog);
42         return strAddress;
43     }
44 
45     if (getLocationRes.GetLocationResult == NULL || (*getLocationRes.GetLocationResult).empty())
46     {
47         CString strLog;
48         strLog.Format(_T("SOAP Result: Error\r\n"));
49         TRACE(strLog);
50         return strAddress;
51     }
52 
53     strAddress = (*getLocationRes.GetLocationResult).c_str();
54     return strAddress;
55 }

 

// 2015.09.15

延伸:C++ 用gSOAP 實現面向Java 開發的 WebService 時,會出現中文亂碼問題;

這是因爲java和gsoap的C++程序對字符串的處理並不一致,Java默認是UTF-8編碼,而C++是ASCII編碼。

爲解決此問題,一個比較好的方法是在gsoap生成的C++代碼中用wchar_t*代替char*,這須要在運行wsdl2h生成gSOAPInterface.h文件時指定必要的類型映射,這能夠利用wsdl2h命令的-t選項來實現。

1)從gsoap的安裝目錄(例如個人是C:\gsoap-2.8)中找到gsoap子目錄,能夠在其中看到一個typemap.dat文件,

這是缺省的類型映射文件

2)將該文件拷貝到當前目錄,並改名爲mytypemap.dat

3)用任意的文本編輯器打開該文件,添加如下代碼:

xsd__string = | wchar_t* | wchar_t*

 

4 )保存更改後的文件,執行解析命令;

舉例:

wsdl2h.exe -t mytypemap.dat -o gSOAPInterface.h http://59.50.104.87:8080/LBS-Environmental/lbsService?wsdl

能夠看到,新生成的gSOAPInterface.h 文件中,字符串的聲明變成了wchar_t*。

5 ) 根據前面的方法執行 soapcpp2.exe;

舉例:

soapcpp2.exe gSOAPInterface.h -C -L -x -i -I ..\..\import

這樣字符串處理以後,字符串以 wchar_t* 的方式傳入就OK了。

 

固然在初始化的時候要加入如下代碼:

1      struct soap *soapclient1 = soap_new();
2         soap_init(soapclient1);
3         soapclient1->recv_timeout = 10;
4         soapclient1->send_timeout = 10;
5         soapclient1->connect_timeout = 10;
6         soap_set_mode(soapclient1, SOAP_C_UTFSTRING);
7     soapclient = (int *)soapclient1;
8    
GoSoapClient = (int *)new ILbsServiceHttpBindingProxy();

結束加入:

1    soap_destroy((soap *)soapclient);
2     soap_end((soap *)soapclient);
3     soap_done((soap *)soapclient);
4     delete soapclient;
5     delete GoSoapClient;

 

//2015.10.10

今天又遇到中文亂碼的問題。

根據上面的方法仍是不行。

so 又進行了調試。

解決方案跟上面相似,但用上面的方法不行的緣由是。

以前解析出來的字符串類型是 

 

 

能夠用mytypemap 替換掉。

今天是  

 

 

因此今天採用手動替換, 

在解析的 gSOAPInterface.h 中, 有中文的string 所有換成wchar_t *。

而後執行 soapcpp2.exe gSOAPInterface.h -C -L -x -i -I ..\..\import

盡然能夠了。

相關文章
相關標籤/搜索