Gsoap使用心得


           最近用到vc mfc 調用c#寫的wcf 發布的webservice 上傳文件.服務器端接收object 類型的byte[]數組。

           我本來還以為vs2010中vc能象c#一樣方便的使用web service(記得vs2005,vs2008的vc clr 可以直接增加引用),可是找了半天頭大了!!

           網上找了下,大家都是用的gsoap,但是能查到的資料,都是接收簡單數據的,於是效仿,對gsoap生成的代理類,和數據類型研讀,問題解決了。

    1、 先了解一下Gsoap

          gSOAP一種跨平台的C和 C++軟件開發工具包。生成C/C++的RPC代碼,XML數據綁定,對SOAP Web服務和其他應用形成高效的具體架構解析器,它們都受益於一個XML接口。

     這個工具包提供了一個全面和透明的XML數據綁定解決方案,Autocoding節省大量開發時間來執行SOAP/XML Web服務中的C/C++。此外,使用XML數據綁定大大簡化了XML自動映

     射。應用開發人員不再需要調整應用程序邏輯的具體庫和XML為中心的數據,如 交涉DOM。

          我們可以使用gSOAP提供的工具直接根據wsdl文檔,生成所需要的數據類型,並將底層實現完全封裝,我們只需要簡單的操作代理類,就可以很輕松的實現調用。

     2、  Gsoap優點

           誇平台。支持linux386(MAC OS X universal binaries),macosx(Linux i386 compatible),win32(Windows 386 compatible)等。

           穩定性:該軟件已經成熟。自2001年以來經過幾年的發展和試驗。許多工業項目和產品都在使用該軟件。

           開源:可選擇自由和商業許可。

           C和C++的支持:支持純粹的ANSI C和混合的C/C++應用開發。

           行業標准協議: SOAP 1.1/1.2 WSDL 1.1,v2和UDDI 。支持XML架構原始XSD結構類型等等。

 

      3、 不廢話了直接按地址下載:

           下載地址:http://sourceforge.net/projects/gsoap2

           解壓gsoap_2.8.14.zip

           在目錄gsoap-2.8\gsoap\win32下,存在2個exe 文件:

           soapcpp2.exe  該工具轉換WSDL和XSD文件到帶有注釋的C/C++定義文件。

            Wsdl2h.exe  該工具從帶有注釋的C/C/++定義文件生成RPC代碼和XML序列化

 

           在目錄gsoap-2.8\gsoap\doc下幫助文襠。

           首先用C# wcf寫個測試用的服務端代碼(wcf 3.5):

           發布的方法如下:

          

public int testAdd(int intA, int intB)
{ 
      Return  intA+intB;
}

public string upDateFile(string  ilename, object objfile)
{ 
      Byte[] mt=(byte) objfile;
      …………………
}

 

           然后啟動,發布成web service .地址為http://127.0.0.1:2002/myBehavior?wsdl

          其次:用Vc進行調用完成客戶端功能,實現步驟如下:

          開始-運行-cmd進入dos模式,進入gsoap-2.8\gsoap\win32目錄。

          1、  根據wsdl文檔生成頭文件.

          Wsdl2h  -1 –t  ..\..\typemap.dat  -s -0  test.h   http://127.0.0.1:2002/myBehavior?wsdl

          參數只寫了幾個常用的,其他的可以查詢幫助。

-t file

use type map file instead of the default file typemap.dat

-s

don’t generate STL code (no std::string and no std::vector)

-o file

output to file

 

 

 

 

 

 

         2、 soapcpp2.exe -C -L -j -d "C:\test" -w -x "test.h" 

         注意:1、 如果不使用–t參數的話,默認soapcpp2相同的目錄。

                  2、我所使用的服務端使用的是basehttpbinding 支持soap 1.0 (ws(*)HttpBinding 支持soap 2.0)所以使用參數 -1, 如果不設置此參數,將默認soap 1.2版本。

-C

Generate client-side code only

-L

Do not generate soapClientLib/soapServerLib

-j

Generate C++ service proxies and objects that can share a soap struct

-d <path>

Save sources in directory specified by <path>

-w

Do not generate WSDL and schema files

-x

Do not generate sample XML message files

-1

Generate SOAP 1.1 bindings

-2

Generate SOAP 1.2 bindings

 

 

 

 

 

 

 

 

 

 

 

 

將如下文件列表

 

 

 

 

 

 

 

 

 

 

 

 

        BasicHttpBinding_USCOREIDataService.nsmap

        soapBasicHttpBinding_USCOREIDataServiceProxy.cpp

        soapBasicHttpBinding_USCOREIDataServiceProxy.h

        soapC.cpp

        soapH.h

        soapStub.h

        將生成文件及stdsoap2.c,soap12.h,stdsoap2.cpp,加入到工程,

       1、右鍵選擇soapC.cpp、soapBasicHttpBinding_USCOREIDataServiceProxy.cpp、stdsoap2.cpp,點擊"屬性",如下圖所

 

 

         2、選擇 預編譯-》預編譯頭設置為 不使用預編譯頭文件。

 

 

       在使用代碼中加入頭文件:

      #include "soap\ soapBasicHttpBinding_USCOREIDataServiceProxy.cpp "
      #include
"soap\ BasicHttpBinding_USCOREIDataService.nsmap"


      代碼實現部分如下:

struct soap clientSOAP;
soap_init(&clientSOAP);


//簡單的傳值沒有什么疑問
struct _ns1__ testAdd testAdd;
struct _ns1__ testAdd Response testAddResponse;

xsd__int intA;
intA. __item=5;
xsd__int intB;
intB. __item=3;

testAdd. intA = intA;
testAdd. intB = intB;
BasicHttpBinding_USCOREIDataServiceProxy test;

 

test.soap_endpoint=”http://127.0.0.1:2002/myBehavior?wsdl”;

int soapResult= test. testAdd (&testAdd,& testAddResponse);
if(soapResult==SOAP_OK)
{
       Int result= testAddResponse. testAddResult;
}
else
{
       int m=GetLastError();
        ………
}
/*
web service 定義的object類型數據,在wsdl xml 中被定義為xsd:anyType,
而對應代理類中的xsd__anyType,要確認參數實際內容,需要獲得接口的幫助,確定傳值。本實例測試傳輸的是byte數組,二進制。
*/

struct _ns1__ upDateFile upDateFile;
struct _ns1__ upDateFileResponse upDateFileResponse;

   

//先將數據傳給基礎byte類型
// vobjFile

xsd__base64Binary  v ;
v.__ptr=new BYTE[vobjFileSize];
v.__size=vobjFileSize;
memcpy(v.__ptr,vobjFile, vobjFileSize);
v.soap=&clientSOAP;

//將基礎類型傳給從,xsd__anytype派生來的byte

xsd__base64Binary_ *v1 =new xsd__base64Binary_() ;
v1->__item=v;
upDateFile.objName=vFileName;

//生成代理類的時候,xsd:anytype,對應生成 xsd__anytype
upDateFile.objPgc=v1;
BasicHttpBinding_USCOREIDataServiceProxy test;

test.soap_endpoint=”http://127.0.0.1:2002/myBehavior?wsdl”;

int soapResult= test.upDateFile(&upDateFile,& upDateFileResponse);
if(soapResult==SOAP_OK)
{

     char *result;
     result=new char[10];
     result= upDateFileResponse. 
     upDateFileResponseResult;

     delete result;
     if (atoi(result)==0)
     {
           ………

     }
}
else
{
      int m=GetLastError();
       ………
}
    
delete v1;
upfile.destroy();

 

問題解決!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM