使用 gsoap 发送 qt 对象
Send qt object with gsoap
我想用 gsoap 发送 qt 对象,例如 qlist 或 qstring 或 qimage 或 qbytearray ...?
根据我对 gsoap 的了解,我们只能发送原始类型的数据,如 char * 或 int ...。
例子 :
在客户端我有一个这样的结构
Struct mystr
{
QString x;
QImage y;
QbyteArray z;
...
}
QList<mystr> mylist;
我用 100000 个数据结构填充此列表,我想将其发送到服务器。怎么做到的?
如果有帮助,最近发布的 gsoap 工具包 2.8.34 现在支持 XML 中的 QT 基元类型和 QT 容器的序列化,而且工作量很小。
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++ 类型名称的一部分C++ 类型名称。这是一个 gsoap 约定。
在此头文件上 运行ning 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>
对于 soapcpp2,您可以使用选项 -0
(破折号零)摆脱 SOAP 内容。
如果要在此模式中为 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).
希望这对您有所帮助。
我想用 gsoap 发送 qt 对象,例如 qlist 或 qstring 或 qimage 或 qbytearray ...? 根据我对 gsoap 的了解,我们只能发送原始类型的数据,如 char * 或 int ...。 例子 : 在客户端我有一个这样的结构
Struct mystr
{
QString x;
QImage y;
QbyteArray z;
...
}
QList<mystr> mylist;
我用 100000 个数据结构填充此列表,我想将其发送到服务器。怎么做到的?
如果有帮助,最近发布的 gsoap 工具包 2.8.34 现在支持 XML 中的 QT 基元类型和 QT 容器的序列化,而且工作量很小。
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++ 类型名称的一部分C++ 类型名称。这是一个 gsoap 约定。
在此头文件上 运行ning 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>
对于 soapcpp2,您可以使用选项 -0
(破折号零)摆脱 SOAP 内容。
如果要在此模式中为 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).
希望这对您有所帮助。