简体   繁体   中英

How to allocate a C++ Object in Gsoap

I have a soap response structure that contains an optional error parameter (I've abbreviated these hopefully it hasn't created syntax errors). Both classes are generated by gsoap.

Response Object

class SOAP_CMAC ns1__LoginResponse : public ns1__Response
{
public:
    class ns1__Error *Error;    /* optional element of type ns1:Error */
    int *SessionID; /* SOAP 1.2 RPC return element (when namespace qualified) */    /* optional element of type xsd:int */
public:
    virtual int soap_type() const { return 127; } /* = unique type id SOAP_TYPE_ns1__LoginResponse */
    virtual void soap_default(struct soap*);
    virtual void soap_serialize(struct soap*) const;
    virtual int soap_put(struct soap*, const char*, const char*) const;
    virtual int soap_out(struct soap*, const char*, int, const char*) const;
    virtual void *soap_get(struct soap*, const char*, const char*);
    virtual void *soap_in(struct soap*, const char*, const char*);
             ns1__LoginResponse() { ns1__LoginResponse::soap_default(NULL); }
    virtual ~ns1__LoginResponse() { }
};

Error Object

class SOAP_CMAC ns1__Error : public xsd__anyType
{
public:
    std::string *Code;  /* optional element of type xsd:string */
    std::string *Description;   /* optional element of type xsd:string */
public:
    virtual int soap_type() const { return 100; } /* = unique type id SOAP_TYPE_ns1__Error */
    virtual void soap_default(struct soap*);
    virtual void soap_serialize(struct soap*) const;
    virtual int soap_put(struct soap*, const char*, const char*) const;
    virtual int soap_out(struct soap*, const char*, int, const char*) const;
    virtual void *soap_get(struct soap*, const char*, const char*);
    virtual void *soap_in(struct soap*, const char*, const char*);
             ns1__Error() { ns1__Error::soap_default(NULL); }
    virtual ~ns1__Error() { }
};

When I detect an error in my service I have to allocate this ns1__Error object.

I have tried using soap_malloc

ns1__Error* err = (ns1__Error*)soap_malloc(soap_context, sizeof(ns1__Error));

but I have realised this is fatally flawed. When gsoap later calls one of the objects methods, it crashes. The objects constructor has not been called.

If I call soap_malloc then use a placement new to call the constructor then it works but I have no place to call the destructor.

void* errmem = soap_malloc(soap_context, sizeof(ns1__Error));
ns1__Error err= new (errmem) ns1__Error();

This does not crash but feels wrong, especially as gsoap made me the class and made it so I have to allocate it myself, yet doesn't seem to give me a mechanism to do just that. It will also leave my object in a potentially wrong state at deallocation time, as the destructor has not been called.

There is (admittedly dated) talk of a soap_new_Class function, but I do not see this in version 2.8.18.

How can I make this allocation, so that the object is allocated, constructed and destructed properly and gsoap can clean it up once it has finished with it?

Gsoap defines an allocation function for every type it creates from your wsdl or header file.

For a type X it will define a function similar to

X* soap_new_X(struct soap* s, int num = -1);

EDIT: It would seem in the question I misunderstood soap_new_Class as meaning a literal function name.

Which returns a num length array of allocated object of type X (seems -1 is a special case which means just allocate a single object). This is included in gsoaps internal registry of objects to be deallocated when you make a call to soap_destroy , after your request has been served.

For my error object it looks like.

inline ns1__Error * soap_new_ns1__Error(struct soap *soap, int n = -1);

There is a second function created

ns1__Error * soap_new_req_ns1__Error(struct soap *soap, int mandatory_param);

This will allocate the object but also allows setting of any mandatory parameters.

These functions prototypes are defined in SoapH.h. I think the name of the file will change depending on the parameters you pass when you generate your code.

To allocate a std::string, which is common in gsoap (or at least my use thereof) there is the function.

inline std::string * soap_new_std__string(struct soap *soap, int n = -1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM