天天看點

gsoap進行soap開發 1 通過wsdl檔案生成.h檔案 2 由.h檔案生成所需要的cpp/c檔案 3 client例子 4 server例子

1 通過wsdl檔案生成.h檔案

從WSDL中産生頭檔案

用法:

wsdl2h -o 頭檔案名 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裡寫

2 由.h檔案生成所需要的cpp/c檔案

用法

soapcpp2 頭檔案      

例:

soapcpp2 ayandy.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 \path\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)。

------------------------------------------

工程中所要包含的檔案(不是include的)有:

soapStub.h  soapH.h     stdsoap2.h      AbysalEmail.h (這個檔案時第一步生成的頭檔案)

            soapC.cpp   stdsoap2.cpp    soapClient.cpp (用戶端) soapServer.cpp(伺服器端)

程式中include的頭檔案有

#include "soap/ServiceSoap.nsmap"//命名空間,這個必不可少

#include "soap/soapH.h

#include "soap/soapServiceSoapProxy.h" //如果使用代理類

調用哪些方法 可以去 soapStub.h 去找

3 client例子

首先用wsdl2h生成頭檔案,URL可以先用http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl這個。使用-c參數來生成純c代碼。

wsdl2h -c -o quote.h http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

生成的quote.h為:

//gsoap ns1 service name: net_DOTxmethods_DOTservices_DOTstockquote_DOTStockQuoteBinding 
//gsoap ns1 service type: net_DOTxmethods_DOTservices_DOTstockquote_DOTStockQuotePortType 
//gsoap ns1 service port: http://66.28.98.121:9090/soap 
//gsoap ns1 service namespace: urn:xmethods-delayed-quotes 
//gsoap ns1 service documentation: Definitions generated by the gSOAP WSDL parser 1.0 
// Service net.xmethods.services.stockquote.StockQuoteService : net.xmethods.services.stockquote.StockQuote web service 
//gsoap ns1 service method-style: getQuote rpc 
//gsoap ns1 service method-encoding: getQuote http://schemas.xmlsoap.org/soap/encoding/ 
//gsoap ns1 service method-action: getQuote urn:xmethods-delayed-quotes#getQuote 
int ns1__getQuote(char *symbol, float &Result);
           

然後使用soapcpp2指令,來生成c代碼檔案。

soapcpp2 -c quote.h

将會生成如下方法:

int soap_call_ns1__getQuote(struct soap *soap, char *URL, char *action, char *symbol, float &Result);

用戶端可以如下編寫:

#include "soapH.h" // obtain the generated stub  
#include "Quote.nsmap" // obtain the generated XML namespace mapping table for the Quote service  
main()  
{  
   struct soap *soap = soap_new(); 
   float quote;  
   if (soap_call_ns1__getQuote(soap, NULL, NULL, "IBM", quote) == SOAP_OK)  
      printf("Current IBM Stock Quote = %g\n", quote); 
   else // an error occurred  
      soap_print_fault(soap, stderr); // display the SOAP fault on the stderr stream  
}
           

c++用戶端可以使用代理類來寫代碼:

#include "soapQuoteProxy.h" // get proxy 
#include "Quote.nsmap" // get namespace bindings 
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; 
}
           

4 server例子

首先自己寫頭檔案calc.h,該伺服器提供三個方法:計算加法,減法,平方。

// Contents of file "calc.h":  
//gsoap ns service name: calculator 
//gsoap ns service style: rpc 
//gsoap ns service encoding: encoded 
//gsoap ns service port: http://mydomain/path/calculator.cgi 
//gsoap ns service namespace: urn:calculator 
int ns__add(double a, double b, double &result);  
int ns__sub(double a, double b, double &result);  
int ns__sqrt(double a, double &result);
           

然後使用soapcpp2指令來生成源檔案。

soapcpp2 calc.h

編寫提供方法的實作,calc.cpp檔案:

// Contents of file "calc.cpp":  
#include "soapH.h"  
#include "calculator.nsmap"  
#include <math.h>  
main()  
{  
   soap_serve(soap_new()); // call the incoming remote method request dispatcher  
}  
// Implementation of the "add" remote method:  
int ns__add(struct soap *soap, double a, double b, double &result)  
{  
   result = a + b;  
   return SOAP_OK;  
}  
// Implementation of the "sub" remote method:  
int ns__sub(struct soap *soap, double a, double b, double &result)  
{  
   result = a - b;  
   return SOAP_OK;  
}  
// Implementation of the "sqrt" remote method:  
int ns__sqrt(struct soap *soap, double a, double &result)  
{  
   if (a >= 0)  
   {  
      result = sqrt(a);  
      return SOAP_OK;  
   }  
   else 
   {  
      return soap_sender_fault(soap, "Square root of negative value", "I can only compute the square root of a non-negative value"); 
   }  
} 
           

最後編譯calc.cpp soapServerLib.cpp 生成server伺服器。

繼續閱讀