1. 程式人生 > >gsoap2.8交叉編譯過程筆記

gsoap2.8交叉編譯過程筆記

最近在交叉編譯gsoap的時候總出現錯誤,仔細研究試驗記錄成功編譯步驟。

1.解壓gsoap-2.8,複製兩份,命名為gsoap-x86和gsoap-arm

2.編譯x86下庫,進入gsoap-x86目錄,執行 ./configure ,make, su -c 'make install'

3.編譯arm下庫,進入gsoap-arm:

   ./configure --prefix=/usr/local/gsoap-arm --host=arm-hisiv300-linux

  然後修改config.h,

  (1). 將#define malloc rpl_malloc 屏 蔽;                     

  (2).將#define HAVE_MALLOC 0    更改為:#define HAVE_MALLOC 1

4然後執行make,可能會出現錯誤:

   ../../gsoap/src/soapcpp2: cannot execute binary file

原因是需要使用便生成的soapcpp2,但是x86下不能執行arm下的執行程式,於是就把這個檔案重名名,

然後把x86下的gsoap/src/soapcpp2檔案複製一份過來,然後繼續執行make,編譯成功,然後再把這個檔案用以前備份的替換掉,當然也可以直接刪除,然後在gsoap/src/目錄下執行make,重新生成即可

5.執行make install

編譯中遇到的問題;

遇到的編譯出錯問題網上均可以找到答案.

make環境問題:

(1)ylwrap: line 176: yacc: command not found。yacc是一個生成語法分析器的工具。

 #yum install yacc

(2)missing: line 81: flex: command not found。

#yum install flex (需重新配置安裝路徑)

(3)/usr/bin/ld: cannot find -ly。

#yum install yum install bison-devel

(4)../../gsoap/stdsoap2.h:690:19:error:zlib.h:No such file or directory

#yum install zlib-devel

(5)error: openssl/bio.h:  No such file or directory

#yum install openssl-devel


注意,在編譯wsdl中,要用到zlib 和ssl庫,需要用hisi編譯器編譯成功並放到wsdl(/gsoap-2.8/gsoap/wsdl)目錄下放可編譯通過。

生成C++檔案

一. 開發環境準備

本例下載的是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,

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

2. 使用gSoap工具wsdl2h,根據WSDL生成一個C/C++語法結構的標頭檔案。

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

該步的目的:實現WSDL檔案到.h檔案的資料對映

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

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

./soapcpp2 -i -x -C -p Hisi_ SommocService.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裡寫。

引數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