2017-03-23 111 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

希望這會有所幫助。