問題描述: 原來的項目工程是在VS2005上編譯的,用VC寫的,而我現在用的VS2008,在編譯時間報錯說“atlsoap.h”: No such file or directory,網上尋找解決方案是http://www.enjoyit.com.cn/bbs/dispbbs_36_5649.html。最近在上面改代碼,重新編譯時間發現又有問題:error PRJ0003 : 產生“sproxy.exe”時出錯。 方法: 我後來在source裡找到SProxy,編譯一下這個項目。剛開始沒弄成功是因為檔案夾的屬性是唯讀,去掉後,重新編譯就可以。最後把產生的sproxy.exe(Debug檔案夾裡),放到你安裝VS的目錄../Microsoft Visual Studio 9.0/VC/bin裡就可以解決問題了。
Visual Studio 2008以及以後版本中,微緩停止了非託管C++的直接WebService引用。不過ATL Server代碼已經託管到開源網站上,我們可以找到ATL Server的原始碼,編譯出Sproxy.exe,這個工具可以根據wsdl檔案來產生非託管的代理類。這個代理類還需要配合一些標頭檔才能一起使用,這個相關的標頭檔都包含在ATL Server 的原始碼內。 1. 第一步需要使用sproxy.exe工具來組建代理程式類。在vs2008以前的版本,比如vs2005,本身就帶有這個命令,但在vs2008版,已經把它給去除了。需要去http://atlserver.codeplex.com/下載ATL_Server原始碼(最新的ATL_Server_Source_and_Headers_9_0_70425_Alpha)並編譯產生sproxy.exe工具。 注意:在編譯時間出現atl*.h檔案未找到時,需要將ATL_Server_Source_and_Headers_9_0_70425_Alpha目錄下的include檔案找到並複製入 C:\Program Files\MicrosoftVisual Studio 10.0\VC\atlmfc\include(即VC的安裝目錄)中。 2. 為了測試webservice服務,我在網上找了一個提供webservice的網站:http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx它提供天氣預報服務。它的WSDL檔案在這個:http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL把這個檔案儲存為本地檔案,名字叫WeatherWS.wsdl。為了方便,我假定這個檔案和sproxy.exe放在同一個目錄下,執行命令 sproxy.exe /wsdl WeatherWS.wsdl 就會在同目錄下產生WeatherWS.h檔案。 3. 開啟vs2008,建立一個MFC項目WebService,添加WeatherWS.h檔案到項目的標頭檔中。項目中設定ATL_Server的include目錄路徑。在WebServiceDlg.cpp檔案中添加 #include"WeatherWS.h" using namespace WeatherWS; 4. 這些做完以後,就可以調用webservice服務了,具體請參考附件的代碼。 [cpp] view plain copy CoInitialize(NULL); HRESULT hr = S_OK; CWeatherWST<CSoapSocketClientT<>>* m_srv = newCWeatherWST<CSoapSocketClientT<>>; CComBSTR cityCode= ""; //參數為空白預設返回上海的天氣情況 CComBSTR userId= ""; CComBSTR * bstrOut= NULL; int size; CString strUrl= _T("http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx"); m_srv->SetUrl(strUrl);//設定url地址 m_srv->SetTimeout(5000);//設定逾時(參數毫秒) hr = m_srv->getWeather(cityCode,userId, (BSTR* *)&bstrOut, &size); int nErrorCode = m_srv->GetStatusCode(); if(FAILED(hr)) { MessageBox(L"調用失敗"); } else { for (int i = 0; i < size; i++) { bstrOut[i].Append("\r\n"); } if(bstrOut!=NULL) { for(int i=size-1;i>=0;i--) { ::SysFreeString(bstrOut[i]); } bstrOut = NULL; } } if (m_srv != NULL) delete m_srv; CoUninitialize();
SPROXY.EXE 是一個命令列工具,它產生基於 WSDL 說明訪問 XML Web services 的本機 C++ 用戶端代碼。 命令列文法如下所示: 複製 sproxy [ options ] [/out:outputfile ] input_location參數 options (可選)一個或多個下列選項:
選項 |
說明 |
/? 或 /help |
顯示使用資訊。 |
/nologo |
取消顯示著作權訊息。 |
/nowarn |
禁用所有警告。 |
/nopragma |
不將“#pragma once”插入輸出檔案。 |
/noclobber |
如果輸出檔案已存在,則不改寫它。 |
/nonamespace |
不將 C++ 命名空間插入產生的代理檔案。預設情況下,SPROXY 插入一個基於 WSDL 服務名的命名空間。 |
/namespace:<name> |
將名為 <name> 的命名空間插入產生的代理檔案。預設情況下,SPROXY 插入一個基於 WSDL 服務名的命名空間。 命名空間必須是有效 C++ 標識符。當 <name> 為空白時,/namespace:<name> 選項的效果與 /nonamespace 相同。 |
/wsdl <input_location> |
處理位於指定路徑 <input_location> 的 .wsdl 檔案,而不是預設的 .discomap 檔案。 |
outputfile (可選)產生的程式碼將寫入的檔案的名稱。如果該檔案存在,除非指定 /noclobber,否則將改寫它。如果未指定 outputfile,SPROXY 將在目前的目錄中基於WSDL 服務名建立一個檔案。 input_location 對產生其代理代碼的XML Web services 進行描述的檔案的位置。input_location可以是.discomap 或.wsdl 檔案的URL 或檔案系統路徑。使用.wsdl 檔案時請指定 /wsdl選項。 SPROXY.EXE 也可以處理 results.discomap 檔案。請注意,.discomap 檔案包含指向 .wsdl 檔案本機複本的連結,並且使用架構檔案的本機複本。備忘 SPROXY.EXE 將產生一個從 CSoapRootHandler 派生的代理類模板以及它的模板參數。模板參數需要符合 SOAP 用戶端原型且預設為 CSoapSocketClientT<>。 服務公開的每個 SOAP 方法由代理類中的一個方法表示。若要訪問 XML Webservices,請建立代理類的執行個體並調用適當的方法。 在 Visual C++ 安裝程式的 \vc7\bin 目錄中可以找到 SPROXY.EXE。 有關 SPROXY 支援的類型列表,請參見支援的類型和用 ATL Server 建立的 XML Web services 中受支援的類型。 注意 SPROXY產生的用戶端需要MSXML3。在運行該用戶端之前,將需要在安裝所產生的用戶端的電腦上安裝MSXML3。 Xmlinst.exe 在替換模式下安裝 MSXML3。請從MSDN 的 http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/001/469/msdncompositedoc.xml 下載 Xmlinst.exe 替換模式工具。 有關使用Xmlinst.exe 的資訊,請參見知識庫的文章:“PRB:在生產伺服器上運行 Xmlinst.exe 之後出現的應用程式錯誤”(Q278636)。可以在MSDN Library CD-ROM 中或 http://support.microsoft.com/support/ 上找到知識庫文章。 有關運行MSXML3 的資訊,請參見在替換模式下運行 MSXML 3.0。 注意 SPROXY產生的標頭檔包括atlsoap.h。此檔案聲明 [emitidl("restricted")];。如果在遇到 [module]屬性時限制IDL 發出,將發生錯誤。在包括atlsoap.h 後,可以在代碼中使用 [emitidl("true")];以啟用IDL 發出。(atlextmgmt.h包括與atlsoap.h 相同的 emitidl 聲明,因此適應同樣的問題。) 注意 在取值 (Dereference)前,SPROXY 產生的方法不檢查指標參數是否為 NULL。在將指標傳遞給 XML Web services 代理類中的方法前,請檢查指標是否為 NULL。樣本 以下命令列將產生一個檔案 myservice.h,該檔案包含用於訪問從http://myserver/myservice.dll?Handler=GenMyServiceWSDL 擷取的 WSDL 所描述的 XML Webservices 的 C++ 代理代碼: 複製 sproxy /wsdlhttp://myserver/myservice.dll?Handler=GenMyServiceWSDL /out:myservice.h 以下命令列將產生一個輸出檔案,該檔案包含用於訪問從results.discomap(它包含指向 .wsdl 檔案本機複本的連結)中擷取的 WSDL 所描述的 XML Webservices 的 C++ 代理代碼: 複製 sproxyresults.discomap CSoapSocketClientT 類說明 ,參考http://msdn.microsoft.com/zh-cn/subscriptions/0yw680wb(VS.80).aspx |