0

I'm currently developing application using gSoap library and has some misunderstanding of proper usage library. I has generated proxy object (-j flag) which wrapped my own classes, as you can see below. Application must work 24/7 and connect simultaneously to many cameras (~50 cameras), so after every request i need to clear all temporary data. Is it normal usage to call soap_destroy() and soap_end() after every request? Because it seem's overkill to do it after each request. May be exists another option of proper usage?

DeviceBindingProxy::destroy()
{
    soap_destroy(this->soap);
    soap_end(this->soap);
}

class OnvifDeviceService : public Domain::IDeviceService
{
public:
    OnvifDeviceService()
    : m_deviceProxy(new DeviceBindingProxy) 
    { 
        soap_register_plugin(m_deviceProxy->soap, soap_wsse);
    }

    int OnvifDeviceService::getDeviceInformation(const Access::Domain::Endpoint &endpoint, Domain::DeviceInformation *information)
    {
        _tds__GetDeviceInformation tds__GetDeviceInformation;
        _tds__GetDeviceInformationResponse tds__GetDeviceInformationResponse;

        setupUserPasswordToProxy(endpoint);
        m_deviceProxy->soap_endpoint = endpoint.endpoint().c_str();
        int result = m_deviceProxy->GetDeviceInformation(&tds__GetDeviceInformation, tds__GetDeviceInformationResponse);
        m_deviceProxy->soap_endpoint = NULL;
        if (result != SOAP_OK) {
            Common::Infrastructure::printSoapError("Fail to get device information.", m_deviceProxy->soap);
            m_deviceProxy->destroy();
            return -1;
        }

        *information = Domain::DeviceInformation(tds__GetDeviceInformationResponse.Manufacturer,
                                 tds__GetDeviceInformationResponse.Model,
                                 tds__GetDeviceInformationResponse.FirmwareVersion);
        m_deviceProxy->destroy();
        return 0;
    }

}

2 Answers2

3

To ensure proper allocation and deallocation of managed data:

soap_destroy(soap);
soap_end(soap);

You want to do this often to avoid memory to fill up with old data. These calls remove all deserialized data and data you allocated with the soap_new_X() and soap_malloc() functions.

All managed allocations are deleted with soap_destroy() followed by soap_end(). After that, you can start allocating again and delete again, etc.

To allocate managed data:

SomeClass *obj = soap_new_SomeClass(soap);

You can use soap_malloc for raw managed allocation, or to allocate an array of pointers, or a C string:

const char *s = soap_malloc(soap, 100);

Remember that malloc is not safe in C++. Better is to allocate std::string with:

std::string *s = soap_new_std__string(soap);

Arrays can be allocated with the second parameter, e.g. an array of 10 strings:

std::string *s = soap_new_std__string(soap, 10);

If you want to preserve data that otherwise gets deleted with these calls, use:

soap_unlink(soap, obj);

Now obj can be removed later with delete obj. But be aware that all pointer members in obj that point to managed data have become invalid after soap_destroy() and soap_end(). So you may have to invoke soap_unlink() on these members or risk dangling pointers.

A new cool feature of gSOAP is to generate deep copy and delete function for any data structures automatically, which saves a HUGE amount of coding time:

SomeClass *otherobj = soap_dup_SomeClass(NULL, obj);

This duplicates obj to unmanaged heap space. This is a deep copy that checks for cycles in the object graph and removes such cycles to avoid deletion issues. You can also duplicate the whole (cyclic) managed object to another context by using soap instead of NULL for the first argument of soap_dup_SomeClass.

To deep delete:

 soap_del_SomeClass(obj);

This deletes obj but also the data pointed to by its members, and so on.

To use the soap_dup_X and soap_del_X functions use soapcpp2 with options -Ec and -Ed, respectively.

In principle, static and stack-allocated data can be serialized just as well. But consider using the managed heap instead.

See https://www.genivia.com/doc/databinding/html/index.html#memory2 for more details and examples.

Hope this helps.

Dr. Alex RE
  • 1,772
  • 1
  • 15
  • 23
0

The way memory has to be handled is described in Section 9.3 of the GSoap documentation.

Ottavio Campana
  • 4,088
  • 5
  • 31
  • 58