2016-05-03 3 views
1

Я хочу отправить объекты qt, такие как qlist или qstring или qimage или qbytearray ... с gsoap? Основываясь на моей науке о gsoap, мы можем отправлять данные только с примитивным типом типа char * или int .... Пример: В клиенте у меня есть-структура, как этотОтправить qt объект с gsoap

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 теперь поддерживает минимализацию сериализации примитивных типов QT и контейнеров QT в XML с минимальными усилиями.

Типы QT привязаны к типам XSD по имени, в основном просто typedef. Эти типы затем сериализуются с использованием настраиваемого сериализатора, который скомпилирован и связан с вашим кодом.

Возможно, это проще понять с помощью простого примера.

Чтобы использовать QString как сериализуемый тип, просто добавьте #import "custom/qstring.h" в файл заголовка, у которого есть интерфейс привязки данных для soapcpp2. Затем запустите soapcpp2 в файле и скомпилируйте сгенерированный soapC.cpp с stdsoap2.cpp. Не забудьте указать #include "soapH.h" (который также включает soapStub.h).

Вот пример файла заголовка для soapcpp2 с типами, которые вы хотите сериализовать в XML, объявляя их привязки данных и импортировать пользовательские типы QT, которые вы хотите:

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