There are a few things you need to do.
First create your objects in C ++ so that they are obtained from xsd__anyType ( -p option on wsdl2h )
When you compile your code, define WITH_NO_IO and WITH_NO_HTTP so that you don't get gSoap calls by default and IO by default.
Then create a Serializer class, for example (pardon rant about XML):
#pragma once
The implementation looks like this:
#include "MyLibH.h" #include "stdsoap2.h" #include "Serializer.h" namespace MyLib { static int fsend(struct soap* ctx, char const *buf, size_t len) { if (!ctx->os) { throw std::logic_error("soap.fsend the struct soap 'os' member must be set."); } ctx->os->write(buf, len); return SOAP_OK; } static size_t frecv(struct soap* ctx, char* buf, size_t len) { if (!ctx->is) { throw std::logic_error("soap.fsend the struct soap 'is' member must be set."); } ctx->is->read(buf, len); return ctx->is->gcount(); } static SOAP_SOCKET fopen(struct soap*, const char*, const char*, int) { throw std::logic_error("soap.fopen not implemented for Serializer."); } static int fclose(struct soap *ctx) { return SOAP_OK; } static int fclosesocket(struct soap*, SOAP_SOCKET) { throw std::logic_error("soap.fclosesocket not implemented for Serializer."); } static int fshutdownsocket(struct soap*, SOAP_SOCKET, int) { throw std::logic_error("soap.fshutdownsocket not implemented for Serializer."); } static SOAP_SOCKET faccept(struct soap*, SOAP_SOCKET, struct sockaddr*, int *n) { throw std::logic_error("soap.faccept not implemented for Serializer."); } class SerializerImpl { struct soap mutable soap; public: SerializerImpl(); ~SerializerImpl(); struct soap *ctx() const { return &soap; } }; SerializerImpl::SerializerImpl() { soap_init(&soap);
With this class you can create a Serializer ser; , then do ser.Serialize(myEntity, myOutputStream); or auto myEntity = ser.Deserialize(myInputStream); .
You can see the secret of polymorphic deserialization in the Deserialize() method, where it calls soap_getelement() , which returns a void pointer for any type that it can deserialize. Then, if the type is the one that is known to be based on xsd__anyType , then it is converted to shared_ptr<xsd__anyType> using the special delete method that is contained in the context of struct soap , so it can delete gSoap properly, The ability to distinguish xsd__anyType is this is the reason why we told wsdl2h to deduce all our types from this type using the -p option.
Note that in order to make this work for me, I had to create some other functions. The way I built the source with wsdl2h and soapcpp2 , WITH_NOGLOBAL , was defined. This caused some undefined functions. I made the definitions as follows:
#include "MyLib3.nsmap" SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultcode(struct soap *soap) { static char const *ret; ret = nullptr; return &ret; } SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultsubcode(struct soap *soap) { static char const *ret; ret = nullptr; return &ret; } SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultstring(struct soap *soap) { static char const *ret; ret = nullptr; return &ret; } SOAP_FMAC3 const char ** SOAP_FMAC4 soap_faultdetail(struct soap *soap) { static char const *ret; ret = nullptr; return &ret; } SOAP_FMAC3 const char * SOAP_FMAC4 soap_check_faultsubcode(struct soap *soap) { return nullptr; } SOAP_FMAC3 const char * SOAP_FMAC4 soap_check_faultdetail(struct soap *soap) { return nullptr; } SOAP_FMAC3 void SOAP_FMAC4 soap_serializefault(struct soap *soap) { } SOAP_FMAC3 void SOAP_FMAC4 soap_serializeheader(struct soap *soap) { } SOAP_FMAC3 int SOAP_FMAC4 soap_putheader(struct soap *soap) { return SOAP_OK; } SOAP_FMAC3 int SOAP_FMAC4 soap_getfault(struct soap *soap) { return SOAP_OK; } SOAP_FMAC3 int SOAP_FMAC4 soap_putfault(struct soap *soap) { return SOAP_OK; } SOAP_FMAC3 int SOAP_FMAC4 soap_getheader(struct soap *soap) { return SOAP_OK; }