2016-05-03 6 views
1

Ich möchte qt Objekte wie qlist oder qstring oder qimage oder qbytearray ... mit gsoap senden? Basis meiner Wissenschaft über Gsoap können wir nur Daten mit primitiven Typ wie char * oder int ... senden. Beispiel: Im Client habe ich eine Struktur wie dieseSend qt Objekt mit gsoap

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

ich diese Liste mit 100.000 Datenstruktur füllen und ich möchte diese Server senden. Wie kann das gemacht werden?

+0

Das Tool soapcpp2 erkennt 'QString' und andere QT-Typen nicht. Um diese direkt in XML zu serialisieren, müssen Sie benutzerdefinierte Serializer definieren. Ansonsten würde ich Standard-C++ - Typen zum Serialisieren und Konvertieren zu/von QT-Typen verwenden. Vielleicht können Sie den gsoap-Entwicklern vorschlagen, QT-Typ-Serialisierer zu implementieren? –

+0

Ich brauche es jetzt. Bis gsoap Entwickler das implementieren ... – ebigood

Antwort

0

Wenn es hilft, unterstützt die aktuelle Version des gsoap toolkit 2.8.34 jetzt die Serialisierung von QT primitiven Typen und QT-Containern in XML mit minimalem Aufwand.

QT-Typen sind nach Namen an XSD-Typen gebunden, im Grunde genommen nur ein typedef. Diese Typen werden dann mit einem benutzerdefinierten Serializer serialisiert, der kompiliert und mit Ihrem Code verknüpft ist.

Vielleicht ist es einfacher, alles mit einem einfachen Beispiel zu verstehen.

Wenn Sie QString als serialisierbaren Typ verwenden möchten, fügen Sie einfach einen #import "custom/qstring.h" zu Ihrer Header-Datei hinzu, die über die Datenbindungsschnittstelle für soapcpp2 verfügt. Führen Sie dann soapcpp2 für die Datei aus und kompilieren Sie das generierte soapC.cpp mit stdsoap2.cpp. Vergessen Sie nicht, #include "soapH.h" (die auch soapStub.h enthält). Hier

ist ein Beispiel Header-Datei für soapcpp2 mit den Typen, die Sie in XML serialisieren möchten, indem sie als Datenbindungen deklarieren und Importieren der benutzerdefinierten QT-Typen, die Sie wollen:

//////////////////////////////////////////////////////////////////////////// 
// 
// 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 
}; 

Bitte beachte, dass ich habe behielt es einfach, indem es ns: als Präfix anstatt ns__ (ns mit doppelten Unterstrichen) verwendete. Der Unterschied ist, dass ns: wird nicht Teil Ihrer C++ - Typnamen sein, während ns__wird Teil Ihrer C++ Typnamen sein. Dies ist eine Gsoap-Konvention.

Nach soapcpp2 auf dieser Header-Datei ausgeführt wird, erzeugt er ein Schema ns.xsd mit XML-Typ:

<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> 

Sie können mit der Option des SOAP-Zeugs loszuwerden -0 (Strich Null) für soapcpp2.

Wenn Sie ein Stammelement für MyData in diesem Schema definieren möchten, fügen Sie den folgenden in die Header-Datei und Rerun soapcpp2 auf diese Datei:

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

Die XML-Serializer kann wie folgt verwendet werden:

#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). 

Hoffe, das hilft.

+0

Danke, das war so nützlich. – ebigood