В настоящее время я занимаюсь разработкой приложения с использованием библиотеки gSoap, и у меня возникло недопонимание правильного использования библиотеки. Я сгенерировал прокси-объект (флаг -j), который обернул мои собственные классы, как вы можете видеть ниже. Приложение должно работать 24/7 и подключаться одновременно ко многим камерам (~ 50 камер), поэтому после каждого запроса мне нужно очистить все временные данные. Является ли нормальным использование для вызова soap_destroy () и soap_end () после каждого запроса? Потому что это кажется излишним делать это после каждого запроса. Может быть, существует еще один вариант правильного использования?
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;
}
}
Способ обращения с памятью описан в Раздел 9.3 документации GSoap.
Чтобы обеспечить правильное распределение и освобождение управляемых данных:
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_X
а также soap_del_X
функции используют soapcpp2 с опциями -Ec
а также -Ed
соответственно.
В принципе, статические данные и данные, размещенные в стеке, также могут быть сериализованы. Но вместо этого рассмотрите возможность использования управляемой кучи.
Увидеть https://www.genivia.com/doc/databinding/html/index.html#memory2 для более подробной информации и примеров.
Надеюсь это поможет.