2017-03-23 33 views
0

我目前正在开发使用gSoap库的应用程序,并对正确使用库有一些误解。我已经生成了包装我自己的类的代理对象(-j标志),如下所示。应用程序必须全天候工作,并同时连接到许多摄像机(约50台摄像机),因此在每次请求后,我需要清除所有临时数据。每次请求后调用soap_destroy()和soap_end()是否正常使用?因为在每次请求之后执行它看起来过于矫枉过正。可能存在正确使用的另一种选择?gSoap中正确的内存控制

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; 
    } 

} 

回答

0

为了确保管理数据的适当分配和释放:

soap_destroy(soap); 
soap_end(soap); 

你想这样做往往以避免内存使用旧数据来填充。这些调用会删除使用soap_new_X()和soap_malloc()函数分配的所有反序列化数据和数据。

所有托管分配都将删除,其中soap_destroy()后跟soap_end()。在那之后,你就可以开始重新分配和再删除等

要分配管理的数据:

SomeClass *obj = soap_new_SomeClass(soap); 

可以使用soap_malloc为原料管理的分配,或分配指针数组,或C字符串:

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

请记住malloc在C++中不安全。更好的是分配std :: string:

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

数组可以分配第二个参数,例如: 10个字符串数组:

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

如果要保留,否则被这些电话已删除的数据,使用方法:

soap_unlink(soap, obj); 

现在obj以后可以用delete obj去除。但请注意,指向托管数据的obj中的所有指针成员在soap_destroy()soap_end()之后都变为无效。所以你可能不得不在这些成员上调用soap_unlink()或者冒着悬挂指针的风险。

gSOAP的一种新的酷的功能是产生深拷贝和用于自动任何数据结构,从而节省的编码时间量巨大删除功能:

SomeClass *otherobj = soap_dup_SomeClass(NULL, obj); 

此复制obj非托管堆空间。这是一个深层副本,用于检查对象图中的周期并删除这些周期以避免删除问题。您还可以使用soap(而不是NULL)为第一个参数soap_dup_SomeClass复制整个(循环)管理对象到另一个上下文。

深删除:

soap_del_SomeClass(obj); 

这将删除obj而且数据由它的成员指出,等等。

要使用soap_dup_Xsoap_del_X函数分别使用带有选项-Ec-Ed的soapcpp2。

原则上,静态和堆栈分配数据也可以串行化。但考虑使用托管堆代替。

有关更多详细信息和示例,请参见https://www.genivia.com/doc/databinding/html/index.html#memory2

希望这会有所帮助。