gSOAP編譯工具提供了一個SOAP/XML 關於C/C++ 語言的實現,從而讓C/C++語言開發web服務或客戶端程式的工作變得輕鬆了很多。絕大多數的C++web服務工具包提供一組API函式類庫來處理特定的SOAP數據結構,這樣就使得用戶必須改變程式結構來適應相關的類庫。與之相反,gSOAP利用編譯器技術提供了一組透明化的SOAP API,並將與開發無關的SOAP實現細節相關的內容對用戶隱藏起來。
基本介紹
- 軟體名稱:gSoap
- 軟體語言:C/C++
- 特點:跨平台可移植
- 優點:讓C/C++語言開發web服務變得輕鬆
簡介,特點,
簡介
gSOAP的編譯器能夠自動的將用戶定義的本地化的C或C++數據類型轉變為符合XML語法的數據結構,反之亦然。這樣,只用一組簡單的API就將用戶從SOAP細節實現工作中解脫了出來,可以專注與應用程式邏輯的實現工作了。gSOAP編譯器可以集成C/C++和Fortran代碼(通過一個Fortran到C的接口),嵌入式系統,其他SOAP程式提供的實時軟體的資源和信息;可以跨越多個作業系統,語言環境以及在防火牆後的不同組織。
gSOAP一種跨平台的C和 C++軟體開發工具包。生成C/C++的RPC代碼,XML數據綁定,對SOAP Web服務和其他套用形成高效的具體架構解析器,它們都受益於一個XML接口。 這個工具包提供了一個全面和透明的XML數據綁定解決方案,Autocoding節省大量開發時間來執行SOAP/XML Web服務中的C/C++。此外,使用XML數據綁定大大簡化了XML自動映射。套用開發人員不再需要調整應用程式邏輯的具體庫和XML為中心的數據,如 交涉DOM。
特點
可移植性:gSOAP支持大多 數平台,包括嵌入式系統和小系統(例如嵌入式Symbian,Palm)。可移植性測試Windows(98,XP,Vista),Linux,Unix 系統,Mac OS X,Solaris,HP-UX,AIX,FreeBSD,TRU64,Irix,QNX,VxWorks。
穩定性:該軟體已經成熟。自2001年以來經過幾年的發展和試驗。許多工業項目和產品都在使用該軟體。
廣泛的用戶群:自2003年以來超過150000次下載,成千上萬許可證/支持協定的公司,其中包括一些財富100強企業。
所有功能於一身的軟體包:獨立第三方工具和庫確保可靠的運行執行。
開源:可選擇自由和商業許可。
C和C++的支持:支持純粹的ANSI C和混合的C/C++套用開發。
綜合XML數據綁定: gSOAP是唯一的SOAP/XML工具包,支持一個純粹的本地的C/C++數據綁定到XML。該工具包是以自動序列指針為基礎的數據結構。
行業標準協定: SOAP 1.1/1.2 WSDL 1.1,v2和UDDI 。支持XML架構原始XSD結構類型等等。
傳 輸:HTTP/S, TCP, UDP, MIME (SwA), DIME (streaming), MTOM (streaming), HTTP1.0/1.1, IPv4, IPv6, RSS, XML-RPC, WS-Addressing, WS-Enumeration等
安全:HTTPS和WS安全性:認證令牌,數字簽名。
速度:架構特定的編譯器生成的代碼速度快。基準測試表明速度優於最快的XML解析器。
占用記憶體小:客戶端應用程式總運行記憶體占用很小。記憶體管理使用垃圾收集,可以自動清理。
許多例子:軟體包,包括許多代碼範例,其中包括獨立的HTTP/1.1和HTTPS安全的Web伺服器。
Web伺服器整合:包括Apache_mod, IIS, WinInet, CGI, FastCGI。
gSOAP使編寫web服務的工作最小化了。gSOAP編譯器生成SOAP的代碼來序列化或反序列化C/C++的數據結構。gSOAP包含一個WSDL生成器,用它來為你的web服務生成web服務的解釋。gSOAP的解釋器及導入器可以使用戶不需要分析web服務的細節就可以實現一個客戶端或服務端程式。
下面是gSOAP的一些特點:
×gSOAP編譯器可以根據用戶定義的C和C++數據結構自動生成符合SOAP的實例化代碼。
×gSOAP支持WSDL 1.1, SOAP 1.1, SOAP 1.2, SOAP RPC 編碼方式以及 literal/document 方式.
×gSOAP是少數完全支持SOAP1.1 RPC編碼功能的工具包,包括多維數組及動態類型。比如,一個包含一個基類參數的遠程方法可以接收客戶端傳來的子類實例。子類實例通過動態綁定技術來保持一致性。
×gSOAP 支持 MIME (SwA) 和 DIME 附屬檔案包。
×gSOAP是唯一支持DIME附屬檔案傳輸的工具包。它允許你在保證XML可用性的同時能夠以最快的方式(流方式)傳遞近乎無大小限制的二進制數據。
×gSOAP 支持 SOAP-over-UDP。
×gSOAP 支持 IPv4 and IPv6.
×gSOAP 支持 Zlib deflate and gzip compression(for HTTP, TCP/IP, and XML file storage)。
×gSOAP 支持 SSL (HTTPS)。
×gSOAP 支持 HTTP/1.0, HTTP/1.1 保持連線, 分塊傳輸及基本驗證。
×gSOAP 支持 SOAP 單向訊息。
×gSOAP 包含一個 WSDL 生成器,便於web服務的發布。
×gSOAP 包含一個WSDL解析器(將WSDL轉換為gSOAP頭檔案),可以自動化用戶客戶端及服務端的開發。
×生成可以單獨運行的web服務及客戶端程式。
×因為只需要很少記憶體空間,所以可以運行在類似Palm OS, Symbian, Pocket PC的小型設備中。
×適用於以C或C++開發的web服務中。
×跨平台:Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian等。
×支持序列化程式中的本地化C/C++數據結構。
×可以使用輸入和輸出緩衝區來提高效率,但是不用完全訊息緩衝來確定HTTP訊息的長度。取而代之的是一個三相序列化方法。這樣,像64位編碼的圖像就可以在小記憶體設備(如PDA)中以DIME附屬檔案或其他方式傳輸。
×不需要重寫現有的C/C++套用。但是,不能用unions,指針和空指針來作為遠程方法調用參數的數據結構中元素。
×三相編組:1)分析指針,引用,循環數據結構;2)確定HTTP訊息長度;3)將數據序列化位SOAP1.1編碼方式或用戶定義的數據編碼方式。
×雙相編組:1)SOAP解釋及編碼;2)分解“forward”指針(例如:分解SOAP中的href屬性)。
×完整可定製的SOAP錯誤處理機制。
×可定製的SOAP訊息頭處理機制,可以用來保持狀態信息
2 gSoap2.2版與gSOAP 2.1版(或以前版本)的不同
如果你是從2.1版升級到2.2或以後版本,請注意這些變化。
為了能夠分離傳輸、內容編碼、映射中的接收/傳送設定,改變了運行時選項及標誌。這些標誌分布在四個類中:傳輸(IO),內容編碼(ENC),XML編組(XML)及C/C++數據映射。不再提倡使用舊標誌soap_disable_X及soap_enable_X(其中,X表示選項名)。具體內容請參見9.12節。
3. gSoap2.x版與gSOAP 1.x版的不同
如果你是從1.x版升級到2.x版,請注意下面的內容。
gSOAP2.0及之後的版本是在1.x版基礎上重寫的。gSOAP2.0之後的版本是執行緒安全的,但之前版本不是。gSOAP2.x版本中的主要檔案已經重新命名,以便與1.x版區分。
gSOAP 1.X gSOAP 2.X
soapcpp soapcpp2
soapcpp.exe soapcpp2.exe
stdsoap.h stdsoap2.h
stdsoap.c stdsoap2.c
stdsoap.cpp stdsoap2.cpp
從1.x版升級到2.x版並不需要進行大量的代碼重寫工作。所有2.x版相關的函式都定義在stdsoap2.c[pp]檔案中,這個檔案是由gSOAP編譯器自動生成的。所以,用1.x版開發的服務端或客戶端代碼需要進行修改以適應2.x版中函式的變化:在2.x版中,所有的gSOAP函式都增加了一個參數用來保存一個gSOAP運行環境實例。這個參數包括了檔案描述,表,緩衝,標誌位等,它在所有gSOAP函式中都是第一個參數。
gSOAP運行環境實例是一個struct soap類型的變數。當客戶端程式訪問遠程方法前或當服務端程式能夠接收一個請求前,必須先將這個運行環境變數初始化。在2.x版中新增了3個函式來負責這些事情:
函式 解釋
soap_init(struct soap *soap) 初始化環境變數(只需執行一次)
struct soap *soap_new() 定義並初始化環境變數並返回一個該變數的指針
struct soap *soap_copy(struct soap *soap) 定義一個環境變數並從已有的環境變數中拷貝環境信息
環境變數定義好後就可以重複使用而不必再次初始化了。只有當執行緒獨占訪問時,我們才需要一個新的環境變數。例如,下面的代碼分配了一個用於多個遠程方法的環境變數:
int main()
{
struct soap soap;
...
soap_init(&soap); // 初始化環境變數
...
soap_call_ns__method1(&soap, ...); // 調用一個遠程方法
...
soap_call_ns__method2(&soap, ...); // 調用另一個遠程方法
...
soap_end(&soap); // 清除環境變數
...
}
我們也可以像下面這樣定義環境變數:
int main()
{
struct soap *soap;
...
soap = soap_new(); // 定義並初始化環境變數
if (!soap) // 如果不能定義,退出
...
soap_call_ns__method1(soap, ...); // 調用遠程函式
...
soap_call_ns__method2(soap, ...); // 調用另一個遠程函式
...
soap_end(soap); // 清除環境變數
...
free(soap); // 釋放環境變數空間
}
服務端代碼在調用soap_serve函式前,需要定義相關環境變數:
int main()
{
struct soap soap;
soap_init(&soap);
soap_serve(&soap);
}
或者像下面這樣:
int main()
{
soap_serve(soap_new());
}
soap_serve函式用來處理一個或多個(當允許HTTP keep-alive時,參見18.11節中的SOAP_IO_KEEPALIVE標誌)請求。
一個web服務可以用多執行緒技術來處理請求:
int main()
{
struct soap soap1, soap2;
pthread_t tid;
...
soap_init(&soap1);
if (soap_bind(&soap1, host, port, backlog) < 0) exit(1);
if (soap_accept(&soap1) < 0) exit(1);
pthread_create(&tid, NULL, (void*(*)(void*))soap_serve, (void*)&soap1);
...
soap_init(&soap2);
soap_call_ns__method(&soap2, ...); // 調用遠程方法
...
soap_end(&soap2);
...
pthread_join(tid, NULL); // 等待執行緒結束
soap_end(&soap1); // 釋放環境變數
}
在上面的例子中,需要兩個環境變數信息。而在1.x版本中,由於靜態分配環境變數,多執行緒技術是不被允許的(只有一個執行緒可以用這個環境變數調用遠程方法或處理請求信息)。
4 準備工作
要開始用gSOAP創建一個web服務套用, 你需要:
一個C/C++編譯器。
擁有根據作業系統平台創建的可執行的gSOAP的stdsoap2(windows下為stdsoap2.exe)編譯器。
擁有根據作業系統平台創建的可執行的gSOAP的wsdl2h(windows下為wsdl2h.exe)WSDL解析器。
需要'stdsoap2.c'或'stdsoap2.cpp'及'stdsoap2.h'檔案來實現你的SOAP功能。你可以創建一個dll或動態庫以便簡化連線。
如果你要支持SSL(HTTPS)及壓縮的話,可以安裝OpenSSL及Zlib庫。
gSOAP是獨立開發包,不需要任何第三方的軟體支持(除非你要用到OpenSSL及Zlib)。
與平台無關的gSOAP版本需要你下面的工具編譯'soapcpp2'及'wsdl2h'檔案:
一個C++編譯器(用來編譯'wsdl2h'WSDL解析器)。
Bison 或 Yacc
Flex 或 Lex
推薦使用Bison及Flex。
在軟體包samples目錄下有大量的開發實例。可以用'make'來編譯這些例子。這些例子包含了gSOAP中的各個方面。其中,最簡單的例子是one-liners(samples/oneliners)。
5 快速指南
本指南旨在讓你快速開始你的gSOAP開發之旅。閱讀本節的內容,需要你對SOAP 1.1協定及C/C++語法有大體的了解。雖然使用gSOAP編譯器可以直接用C/C++開始編寫web服務及客戶端程式而不需要了解SOAP協定的細節,但是由於我們在本節中使用了大量的實例來說明gSOAP與其他SOAP實現的連線及通訊,所以了解一些SOAP及WSDL協定也是必需的。
5.1 如何使用gSOAP編譯環境來編譯SOAP客戶端程式
'soapcpp2’存根及架構編譯器是可以生成構建C++ SOAP客戶端所需的C++源碼的預編譯器。該預編譯器的輸入參數是一個標準的C/C++頭檔案。這個頭檔案可以由WSDL解析器根據相關的WSDL文檔自動生成。
參見下面的命令:
$ wsdl2h -o quote.h
上面的命令根據制定URL提供的WSDL文檔生成一個C++語法結構的頭檔案。
如果需要生成一個純C的頭檔案,需要一下命令:
$ wsdl2h -c -o quote.h
更多關於WSDL解析器及其選項的細節信息,請參見8.2.10節。
執行上述命令後,quote.h檔案就生成了。其中包含開發客戶端或服務端程式的存根例程定義。SOAP服務遠程方法以函式聲明的方式在這個頭檔案中被定義。C/C++原始碼的存根例程將通過預編譯器自動實現。同時,每個遠程方法的程式框架也被自動生成了,它可以用來建立SOAP服務端程式套用。
SOAP服務的輸入輸出參數可以是簡單的數據類型或複雜的數據結構,可以由WSDL解析器自動生成或手工定義。預編譯器將自動生成序列化/反序列化這些數據的代碼,以便存根例程可以將這些數據以XML的方式編碼或解碼。
6 如何建立客戶端程式代理類
用於C++客戶端程式的代理類信息是由gSOAP 預編譯器自動創建的。為了說明代理類的生成過程,我們在getQuote.h 頭檔案中加入一些信息,以便gSOAP 預編譯器可以生成代理類。這些信息就類似於WSDL 解析器自動生成的頭檔案中就已經包含的信息。
//"getQuote.h"的內容:
//gsoap ns1 service name: Quote
//gsoap ns1 service location:XXX
//gsoap ns1 service namespace: urn:xmethods-delayed-quotes
//gsoap ns1 service style: rpc
//gsoap ns1 service encoding: encoded
//gsoap ns1 service method-action: getQuote ""
int ns1__getQuote(char *symbol, float &Result);
前三行指令用於定義代理類的名稱,服務地址,命名空間。第四行、第五行指令定義了使用SOAP RPC 編碼方式。最後一行定義了可選的SOAPAction。當需要SOAPAction 時,這行信息將提供給每個遠程方法。使用soapcpp2 對該頭檔案進行編譯後,將會產生soapQuoteProxy.h 檔案。它包含下面的內容:
#include "soapH.h"
class Quote
{ public:
struct soap *soap;
const char *endpoint;
Quote() { soap = soap_new(); endpoint = "XXX"; };
~Quote() { if (soap) { soap_destroy(soap); soap_end(soap); soap_done
(soap); free((void*)soap); }};
int getQuote(char *symbol, float &Result) { return soap ? soap_call_ns1__getQuote(soap, endpoint, "", symbol, Result) : SOAP_EOM; };
};
為了能夠在運行時刻對gSOAP 環境變數及命名空間進行定製,上述兩個變數被定義成全局變數。
生成的代理類可以同命名空間表一起包含在客戶端程式中,請看下面的例子:
#include "soapQuoteProxy.h" // 獲得代理類
#include "Quote.nsmap" // 獲得命名空間綁定
int main()
{
Quote q;
float r;
if (q.ns1__getQuote("IBM", r) == SOAP_OK)
std::cout << r << std::endl;
else
soap_print_fault(q.soap, stderr);
return 0;
}
Quote 構造函式定義並初始化了一個gSOAP 運行環境實例。所有的HTTP 及SOAP/XML 進程都被隱藏在後台自動執行。
如果你需要多個命名空間表或要聯合多個客戶端,你可以在執行soapcpp2 時添加參數-n及-p 來生成命名空間表以防止衝突。