gsoap生成webservice呼叫客戶端介面
阿新 • • 發佈:2019-02-19
1.下載gsoap2.8
2.執行
wsdl2h.exe -o XXX.h XXX.wsdl
wsdl檔案可以是本地檔案,也可以是伺服器的wsdl,比如http://192.168.0.122:3333/ws/uss?wsdl
3.生成客戶端程式碼
soapcpp2.exe -L -x -C XXX.h -I .\gsoap-2.8\gsoap\import
4.如果有多個服務,那麼就將要使用名稱空間
手動將生成的.h合併為一個新檔案,比如上面兩個User*.h,合併為新檔案all.h,對照著很容易看出不同,把名稱空間,類宣告等合在一起就行了wsdl2h -nns別名 -N服務名稱空間 -o XXX.h XXX.wsdl wsdl2h -nuseraddns -NUserAddWS -oUserAddWebService.h userAddWebService.wsdl wsdl2h -nuserloginns -NUserLoginWS -oUserLoginWebService.h userLoginWebService.wsdl
soap2cpp -LCx -pCMSWS All.h -I ../../import
拷貝gsoap2.8目錄下的stdsoap2.h,stdsoap2.cpp到程式目錄,並修改stdsoap2.cpp檔案,將其中一個.nsmap檔案包含進去
#include "xxx.nsmap"
5.傳輸中文
呼叫方法轉為utf-8傳輸soap_set_mode( soap*, SOAP_C_UTFSTRING )
如果用qt的QString將轉換
std::string CUIUtils::convertQStrToUTF8Str(const QString& value) { QByteArray arr = value.toUtf8(); return std::string(arr.data()); } QString CUIUtils::convertUTF8StrToQStr(const std::string& value) { return QString::fromUtf8(value.c_str()); }
例子
int CUserDetailInfoWebServiceImpl::getUserInfo(const char* address, CUserDetailInfo* userDetailInfo) { UserDetailInfoWebServiceCXFImplServiceSoapBinding webServiceBinding; if ((NULL != address) && strlen(address) > 0) { webServiceBinding.endpoint = address; } soap_set_mode(webServiceBinding.soap, SOAP_C_UTFSTRING); userDetailInfo->setRetCode(RET_CODE_ERROR_UNKNOWN); UserDetailInfoWS__getUserInfoByUserId request; std::string id = userDetailInfo->getUserId(); request.userId = &id; UserDetailInfoWS__getUserInfoByUserIdResponse response; int ret = webServiceBinding.__UserDetailInfoWS__getUserInfoByUserId(&request, &response); if (SOAP_OK == ret) { if (NULL == response.result) { userDetailInfo->setRetCode(RET_CODE_NULL_OBJECT); userDetailInfo->setErrorDesc("no return value"); return userDetailInfo->getRetCode(); } userDetailInfo->setRetCode(response.result->retCode); if (RET_CODE_SUCCESS != userDetailInfo->getRetCode()) { userDetailInfo->setErrorDesc(*response.result->desc); } else { if (NULL == response.result->userOperateInfo) { userDetailInfo->setRetCode(RET_CODE_NULL_OBJECT); userDetailInfo->setErrorDesc("no return info"); return userDetailInfo->getRetCode(); } userDetailInfo->setDescript(*response.result->userOperateInfo->descript); userDetailInfo->setDepartmentId(*response.result->userOperateInfo->departmentId); userDetailInfo->setEnabled(response.result->userOperateInfo->enable); userDetailInfo->setLoginName(*response.result->userOperateInfo->loginName); userDetailInfo->setPassword(*response.result->userOperateInfo->password); userDetailInfo->setUserName(*response.result->userOperateInfo->name); } } else { userDetailInfo->setRetCode(RET_CODE_SOAP_ERROR); userDetailInfo->setDescript(*soap_faultstring(webServiceBinding.soap)); } return userDetailInfo->getRetCode(); }
6.匯入多個wsdl檔案
wsdl2h.exe -sck -t e:\test\typemap.dat -o onvif.h analytics.wsdl analyticsdevice.wsdl deviceio.wsdl devicemgmt.wsdl display.wsdl event.wsdl imaging.wsdl media.wsdl ptz.wsdl Receiver.wsdl Recording.wsdl remotediscovery.wsdl Replay.wsdl Search.wsdl
7.操作引數:
以下就是wsdl2h的選項:
-o 檔名,指定輸出標頭檔案-n 名空間字首 代替預設的ns
-c 產生純C程式碼,否則是C++程式碼
-s 不要使用STL程式碼
-t 檔名,指定type map檔案,預設為typemap.dat
-e 禁止為enum成員加上名空間字首
type map檔案用於指定SOAP/XML中的型別與C/C++之間的轉換規則,比如在wsmap.dat裡寫
xsd__string = | std::wstring | wchar_t*
那麼SOAP/XML中的string將轉換成std::wstring或wchar_t*,這樣能更好地支援中文。
接著就是講.h檔案生成.cpp檔案
soapcpp2.exe接的選項如下
-C 僅生成客戶端程式碼
-S 僅生成伺服器端程式碼
-L 不要產生soapClientLib.c和soapServerLib.c檔案
-c 產生純C程式碼,否則是C++程式碼(與標頭檔案有關)
-I 指定imp<wbr>ort路徑(見上文) </wbr>
-x 不要產生XML示例檔案
-i 生成C++包裝,客戶端為xxxxProxy.h(.cpp),伺服器端為xxxxService.h(.cpp)。
這裡一般需要帶上-x,不然會生成一大堆的xml檔案。
-i選項也要帶上,不然不會生成soapXXXXBindingService.cpp和soapXXXXBindingService.h檔案
-I 選項一般也要帶上,-I 後接gsoap路徑中import目錄
一般是-I E:\workspace\onvif\gsoap-2.8\gsoap\import;E:\workspace\onvif\gsoap-2.8\gsoap這樣的