2016-05-03 75 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