用gSoap開發 C/C++ 客戶端 連接Web Service

轉載地址: http://blog.csdn.net/zhaiwenjuan/article/details/6590941

少了個安裝步驟

1、下載解壓gsoap文件
2、安裝所需的相關工具
    sudo apt-get install g++
    sudo apt-get install bison
    sudo apt-get install flex
    suod apt-get install openssl
    sudo apt-get install libssl-dev
    sudo apt-get install libgtk2.0-dev libglib2.0-dev
3、./configure
4、make & make install
5、完成安裝

Linux下,利用gSoap開發Web Service C/C++客戶端

2010-11-24 09:59

一. 開發環境準備

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++語法結構的頭文件。

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

這一步將會得到一個頭文件,如: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

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

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

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/gogor/archive/2010/09/20/5896135.aspx



多的不贅述    以上文章已經寫得很明白了 ,只是提醒一下 着重看一下 加粗的字體的內容!!!


但是有一點上面沒有寫過   所以在自己的開發中遇到麻煩了   

注意 此博文最後一段 注4 的內容

設置連接編碼爲utf8     

然而 還有更重要的一點    我們是用代理文件中存在的代理去調用接口的  所以代理也需要設置爲utf8

如下:

int iRet = 0;
	struct soap userinfoSoap;
	soap_init( &userinfoSoap );
	soap_set_mode( &userinfoSoap, SOAP_C_MBSTRING );

	struct _ns1__ismspSendMultSms helloWorld;
	struct _ns1__ismspSendMultSmsResponse helloWorldResponse;
	const char *pcAddr = "http://192.168.2.107:**********";
	ns2__IbnSms ibnSMS;
	ibnSMS.loginName = "賬號";
	ibnSMS.loginPwd = "密碼";
	
	ibnSMS.msgContent = "漢字" ; //"對了嗎?";// "對了嗎?";// ( char* )str.data( );
	//ibnSMS.msgContent = const_cast<char*>();
	ibnSMS.mobileNumber = "152*******";
	helloWorld.args0 = &ibnSMS;


	//helloWorld.soap = &userinfoSoap;
	iSmsSendManagerSoap11BindingProxy smsProxy( SOAP_C_UTFSTRING );
	
	cout << "read SMS" << endl;
	iRet = smsProxy.ismspSendMultSms( pcAddr, "", &helloWorld, helloWorldResponse );
	cout << SOAP_OK << "  " << iRet << endl;
	if ( iRet != 0 )
	{
		printf( "讀取數據失敗" );
	}
	else
	{

		printf( "讀取數據成功:%s", helloWorldResponse  );
	}
	soap_destroy( &userinfoSoap );
	soap_end( &userinfoSoap );
	soap_done( &userinfoSoap );
	getchar( );


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章