2016-05-03 70 views
1

我想通過gsoap發送像qlist或qstring或qimage或qbytearray這樣的qt對象嗎? 基於我關於gsoap的科學,我們只能用像char *或int ...這樣的原始類型發送數據。 例子: 在客戶端我有這樣用gsoap發送qt對象

Struct mystr 
{ 
QString x; 
QImage y; 
QbyteArray z; 
... 
} 
QList<mystr> mylist; 

我填這個名單100000數據結構,我想送這個給服務器的結構。如何做到這一點?

+0

soapcpp2工具不識別'QString'和其他QT類型。要直接在XML中序列化這些,您需要定義自定義序列化器。否則,我會使用標準的C++類型來序列化和轉換爲/從QT類型。也許你可以建議gsoap開發者實現QT類型串行器? –

+0

我現在需要它。直到gsoap開發者實現這個... – ebigood

回答

0

如果有幫助,最近發佈的gsoap工具包2.8.34現在支持以最少的工作量在XML中對QT基元類型和QT容器進行序列化。

QT類型通過名稱綁定到XSD類型,基本上只是一個typedef。然後使用編譯並鏈接到代碼的自定義序列化程序對這些類型進行序列化。

也許這是一個簡單的例子,更容易理解這一切。

要使用QString作爲可序列化類型,只需將#import "custom/qstring.h"添加到具有soapcpp2數據綁定接口的頭文件即可。然後在該文件上運行soapcpp2,並編譯生成的soapC.cppstdsoap2.cpp。不要忘記#include "soapH.h"(其中還包括soapStub.h)。

這裏是與你想通過聲明他們作爲數據綁定和導入所需的定製QT類型的XML序列化類型soapcpp2一個例子頭文件:

//////////////////////////////////////////////////////////////////////////// 
// 
// Import the QT types that we want to bind to XSD types xsd__Type 
// 
//////////////////////////////////////////////////////////////////////////// 

#import "custom/qstring.h"   // typedef QString xsd__string 
#import "custom/qbytearray_base64.h" // typedef QByteArray xsd__base64Binary 

//////////////////////////////////////////////////////////////////////////// 
// 
// Declare QT container template(s) we will use 
// 
//////////////////////////////////////////////////////////////////////////// 

template <class T> class QList; 

//////////////////////////////////////////////////////////////////////////// 
// 
// Define an XML namespace "ns" for our schema 
// 
//////////////////////////////////////////////////////////////////////////// 

//gsoap ns schema namespace: urn:MyTypes 

//////////////////////////////////////////////////////////////////////////// 
// 
// Define C++ types that use the xsd__Type QT types imported above 
// 
//////////////////////////////////////////////////////////////////////////// 

class ns:MyStruct 
{ 
public: 
    xsd__string x;  // a QString object 
    xsd__base64Binary y; // a QByteArray object 
}; 
class ns:MyData 
{ 
public: 
    QList<ns:MyStruct> z; // a QT list of MyStruct 
}; 

請注意,我通過使用ns:作爲前綴而不是ns__ns帶雙下劃線)保持簡單。區別在於ns:不是是您的C++類型名稱的一部分,而ns__將成爲您的C++類型名稱的一部分。這是一個gsoap約定。

這個頭文件運行soapcpp2後,它會生成一個模式ns.xsd與XML類型:

<schema targetNamespace="urn:MyTypes" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:ns="urn:MyTypes" 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="unqualified" 
    attributeFormDefault="unqualified"> 
    <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> 
    <complexType name="MyStruct"><!-- ns:MyStruct --> 
     <sequence> 
     <element name="x" type="xsd:string" minOccurs="1" maxOccurs="1"/><!-- ns:MyStruct::x --> 
     <element name="y" type="xsd:base64Binary" minOccurs="1" maxOccurs="1"/><!-- ns:MyStruct::y --> 
     </sequence> 
    </complexType> 
    <complexType name="MyData"><!-- ns:MyData --> 
     <sequence> 
     <element name="z" type="ns:MyStruct" minOccurs="0" maxOccurs="unbounded"/><!-- ns:MyData::z --> 
     </sequence> 
    </complexType> 
</schema> 

可以擺脫的SOAP的東西與選項-0(破折號零)soapcpp2。

如果你想在這個模式來定義一個根元素MyData,然後添加以下的頭文件,然後重新運行soapcpp2上的文件:

typedef ns:MyData _ns__myRoot; // ns:myRoot is an XML element of type ns:MyData 

XML序列化可以使用如下:

#include "soapH.h" // this is generated by soapcpp2 
#include "ns.nsmap" // this is generated by soapcpp2 
... 
soap *ctx = soap_new1(SOAP_XML_INDENT); // create a context 
MyData data; 
... 
data.push_back(MyStruct()); // populate some data 
ctx->os = &std::cout; 
soap_write__ns__myRoot(ctx, &data); // serialize data in XML 
... 
ctx->is = &std::cin; 
soap_read__ns__myRoot(ctx, &data); // parse data from XML 
... 
soap_destroy(ctx); 
soap_end(ctx); 
soap_free(ctx). 

希望這會有所幫助。

+0

謝謝,這非常有用。 – ebigood