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
盡然能夠了。