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服務器。