天天看點

在linux下,利用gSoap開發Web Service C/C++用戶端

轉載自:http://www.open-open.com/lib/view/open1363244558046.html

      http://blog.sina.com.cn/s/blog_4900f3fb0100j94p.html

一. 開發環境準備

1. 從gSoap官方網站http://gsoap2.sourceforge.net 下載下傳gSoap工具包。

本例下載下傳的是2.7.15的版本。

2. 根據說明文檔(README)配置安裝gSoap工具包。

說明:   一般下載下傳的gSoap工具包中已經包含了生成Web Service用戶端需要用到的兩個工具(可執行檔案):wsdl2h和soapcpp2,一般在gsoap/bin/linux386下。隻是預設情況下,wsdl2h并不支援SSL,即無法通路HTTPS站點,且這兩個工具的版本一般也要低于所在gSoap工具包的版本。

    是以如果想要支援SSL等更多功能,就需要自己重新配置編譯該gSoap工具包,以生成新的sdl2h和soapcpp2。

    反之,如果下載下傳的gSoap工具包中自帶的wsdl2h和soapcpp2已經滿足了你的需求,就可以不必再配置編譯gSoap工具包了;而是直接使用工具包自帶的wsdl2h和soapcpp2。

二. 開發linux下Web Service C/C++用戶端

這裡,我們直接采用gSoap工具包自帶的wsdl2h和soapcpp2工具。

1. 基本流程  

從Web服務提供者處擷取Web Service的WSDL檔案,通常是一個URL,

如:http://www.cs.fsu.edu/~engelen/calc.wsdl

當然也可以是一個WSDL形式的XML檔案。

2. 使用gSoap工具wsdl2h,根據WSDL生成一個C/C++文法結構的頭檔案。  (通過wsdl檔案生成.h檔案)

如:wsdl2h -s -o calc.h http://www.cs.fsu.edu/~engelen/calc.wsdl

wsdl2h常用選項

  • -o 檔案名,指定輸出頭檔案
  • -n 名空間字首 代替預設的ns
  • -c 産生純C代碼,否則是C++代碼
  • -s 不要使用STL代碼
  • -t 檔案名,指定type map檔案,預設為typemap.dat
  • -e 禁止為enum成員加上名空間字首

type map檔案用于指定SOAP/XML中的類型與C/C++之間的轉換規則,比如在wsmap.dat裡寫

這一步将會得到一個頭檔案,如:calc.h

該步的目的:實作WSDL檔案到.h檔案的資料映射。

3. 使用gSoap的預編譯器soapcpp2,根據上一步得到的頭檔案來生成存根檔案(soapStub.h)和用戶端代碼架構。

如:soapcpp2 -i -x -C -L calc.h

這一步将會得到幾個. nsmap、.h和.cpp檔案,如:calc.nsmap、soapC.cpp、soapH.h、soapStub.h、soapcalcProxy.cpp、soapcalcProxy.h

該步的目的:生成相應的底層通信代碼。

備注:

  • soapStub.h    // soap的存根檔案,定義了ayandy.h裡對應的遠端調用模型
  • soapC.c soapH.h  // soap的序列和反序列代碼,它已經包含了soapStub.h,伺服器端與用戶端都要包含它
  • soapClient.c soapClientLib.c // 用戶端代碼,soapClientLib.c檔案則隻是簡單地包含soapClient.c和soapC.c
  • soapServer.c soapServerLib.c // 伺服器端代碼,soapServerLib.c檔案則隻是簡單地包含soapServer.c和soapC.c
  • ServiceSoap.nsmap ServiceSoap12.nsmap // 名空間定義,伺服器端與用戶端都要包含它
  • soapServiceSoapProxy.h soapServiceSoap12Proxy.h // 用戶端的C++簡單包裝(如果頭檔案是純C代碼,這兩個檔案就不會生成)

綜上所述

  • 如果編寫伺服器端,項目裡應該加入soapServerLib.c,代碼裡包含頭檔案soapH.h
  • 如果編寫用戶端,項目裡應該加入soapClientLib.c,代碼裡包含頭檔案SoapH.h(或xxxxProxy.h)
  • 當然,還要加入gsoap庫裡的stdsoap2.cpp檔案(如果是寫C代碼,則加入stdsoap2.c)

如果看到soapcpp2提示:”Critical error: #import: Cannot open file "stlvector.h" for reading.“, 那是因為我們的頭檔案使用了STL(wsdl2h 沒用-s選項),這時要使用-I選項指定gSOAP的 import檔案路徑,這個路徑是"$gsoap\gsoap\import":

soapcpp2 ayandy.h -I D:\gsoap-2.7\gsoap\import      

soapcpp2常用選項

  • -C 僅生成用戶端代碼
  • -S 僅生成伺服器端代碼
  • -L 不要産生soapClientLib.c和soapServerLib.c檔案
  • -c 産生純C代碼,否則是C++代碼(與頭檔案有關)
  • -I 指定import路徑(見上文)
  • -x 不要産生XML示例檔案
  • -i 生成C++包裝,用戶端為xxxxProxy.h(.cpp),伺服器端為xxxxService.h(.cpp)。

4. 實作用戶端例程

在這一步可以簡單地編寫一個main函數,如:(注意包含的頭檔案)

#include "calc.nsmap"

#include "soapcalcProxy.h"  //該頭檔案已經包含了soapH.h

int main(void)

{

printf("very good!/n");

calcProxy service;

{

double result;

if(service.pow(2, 10, result) == SOAP_OK)

{

std::cout << "The value of 2^10 is " << result << std::endl;

}

}

return 0;

}

5. 用gcc編譯用戶端,生成可執行代碼

    編譯需要的檔案有:第3步生成的所有檔案、第4步編寫的main函數所在的檔案,以及gsoap目錄下的stdsoap2.h和stdsoap2.cpp檔案共9個檔案。

如:calc.nsmap、soapC.cpp、soapH.h、soapStub.h、soapcalcProxy.cpp、soapcalcProxy.h、stdsoap2.cpp、stdsoap2.h、main.cpp。

三、注意事項

注1 :wsdl2h的用法(WSDL/schema 解析和代碼生成器)

wsdl2h [opt] 頭檔案名 WSDL檔案名或URL 

wsdl2h常用選項

-o 檔案名,指定輸出頭檔案 

-n 名空間字首 代替預設的ns 

-c 産生純C代碼,否則是C++代碼 

-s 不要使用STL代碼 

-t 檔案名,指定type map檔案,預設為typemap.dat 

-e 禁止為enum成員加上名空間字首 

type map檔案用于指定SOAP/XML中的類型與C/C++之間的轉換規則,比如在wsmap.dat裡寫。

在本例中,使用的是:wsdl2h -s -o calc.h http://www.cs.fsu.edu/~engelen/calc.wsdl

參數s就表示生成不帶STL的C/C++文法結構的頭檔案calc.h。

如果不用s就會生成帶STL的頭檔案,這樣,在後邊的編譯中需要加入STL的頭

stlvector.h,位于:gsoap/import/目錄下。

注2 :soapcpp2的用法(編譯和代碼生成器)

soapcpp2 [opt] 頭檔案名

soapcpp2常用選項

-C 僅生成用戶端代碼 

-S 僅生成伺服器端代碼 

-L 不要産生soapClientLib.c和soapServerLib.c檔案 

-c 産生純C代碼,否則是C++代碼(與頭檔案有關) 

-I 指定import路徑(見上文) 

-x 不要産生XML示例檔案 

-i 生成C++封裝(代理),用戶端為xxxxProxy.h(.cpp),伺服器端為xxxxService.h(.cpp)。

本例中,使用的是:soapcpp2 -i -x -C -L calc.h

注3 :gSoap工具wsdl2和soapcpp所生成檔案的簡單分析

(1) wsdl2生成的具有C/C++文法結構的頭檔案,其作用就是:将XML文法結構的WSDL檔案映射為C/C++文法結構的.h檔案;并為下一步做準備。

(2) soapcpp(采用參數:-i -x -C -L)生成的檔案共有6個檔案:PlayerBeanPortBinding.nsmap、soapC.cpp、soapH.h、soapPlayerBeanPortBindingProxy.cpp、soapPlayerBeanPortBindingProxy.h、soapStub.h。

a. PlayerBeanPortBinding.nsmap檔案

該檔案的作用:An XML-to-C/C++ namespace mapping table,即WSDL檔案與生成的用戶端代碼架構的一個名字空間的映射表。

b. soapStub.h

該檔案就是直接由wsdl2生成的頭檔案轉化而來,它詳細定義了WSDL所描述的各項服務和資料結構。

它是soap的存根檔案,定義了由wsdl2生成的頭檔案裡對應的遠端調用模型(RPC)。

c. soapPlayerBeanPortBindingProxy.和soapPlayerBeanPortBindingProxy.cpp

這兩個檔案是用戶端代碼的一個簡單封裝,它封裝了底層通信,并向外提供一個很簡單的界面,該界面展示了使用者能夠使用的所有服務(由WSDL所描述)。

d. soapH.h和soapC.cpp

這個兩個檔案是soap的序列和反序列化代碼,

注4 :設定字元編碼

   在利用gSoap編寫Web Service用戶端和伺服器端的程式時,需要設定其編碼

           方式。接口為:soap_set_mode,其實它是就是一個宏:

#define soap_set_mode(soap, n) ((soap)->imode |= (n), (soap)->omode |= (n))

如果要設定為UTF8

可以這樣調用:soap_set_mode(&soap, SOAP_C_UTFSTRING);

詳細資訊可參考該宏所在檔案: stdsoap2.h

繼續閱讀