Правильный контроль памяти в gSoap

В настоящее время я занимаюсь разработкой приложения с использованием библиотеки 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;
}

}

0

Решение

Способ обращения с памятью описан в Раздел 9.3 документации GSoap.

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_X а также soap_del_X функции используют soapcpp2 с опциями -Ec а также -Edсоответственно.

В принципе, статические данные и данные, размещенные в стеке, также могут быть сериализованы. Но вместо этого рассмотрите возможность использования управляемой кучи.

Увидеть https://www.genivia.com/doc/databinding/html/index.html#memory2 для более подробной информации и примеров.

Надеюсь это поможет.

0

По вопросам рекламы [email protected]