Функции вызова C ++ в COM DLL Возможная утечка памяти - PullRequest
0 голосов
/ 17 апреля 2019

Я создал консольное приложение C ++ с использованием VC ++ 2017. Со временем он выполняет ряд вызовов для извлечения данных из сторонней библиотеки COM DLL.Я использую COM-классы, такие как CComSafeArray и CComVariant, которые сами управляют освобождением.

Со временем я наблюдаю, что память для моего приложения постоянно увеличивается в диспетчере задач после каждого вызова COM.

Я использовалБиблиотека CRT (https://docs.microsoft.com/en-us/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019), чтобы попытаться обнаружить утечки памяти, но это указывает, что у меня ее нет.

Мой вопрос (ы):

  1. Работает ли COM вообщеделает ли это собственное управление памятью, которое библиотека CRT не может обнаружить, но связана с моим процессом?
  2. Если # 1 имеет место, есть ли инструменты для обнаружения утечек памяти COM?
  3. Если # 1в чем дело, есть ли способ собрать мусор COM памятью?

Спасибо за внимание.

Редактировать 4-19-2019 Я выяснилчто COM Dll возвращает VARIANT и BSTR для результатов вызова функций. Я назначаю их по-разному для _variant_t и _bstr_t, если это применимо, для обеспечения автоматической очистки (теоретически). Например.

_variant_t v = GetSomeVariant();
_bstr_t b = GetSomeString();

DLL не использует CoTaskMemAlloc, но он использует SysAllocString для генерации BSTR.

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

COM не использует никакой автоматической сборки мусора; все должно быть учтено, хотя есть вспомогательные классы, которые занимаются подсчетом ссылок.

Соглашение в COM заключается в том, что если вызываемый метод выделяет некоторую память, то вызывающая сторона должна освободить ее с помощью CoTaskMemFree. Возможно, вы захотите проверить свой код на наличие методов DLL, которые вы вызываете, и если они возвращают что-либо в буфере, который был выделен DLL, то вам нужно освободить этот буфер, вызвав CoTaskMemFree.

См. https://docs.microsoft.com/en-us/windows/desktop/learnwin32/memory-allocation-in-com

Подробнее здесь: https://docs.microsoft.com/en-us/windows/desktop/com/memory-management-rules

0 голосов
/ 19 апреля 2019

_bstr_t b = GetSomeString();

Предположительно, это BSTR GetSomeString();. Что для компилятора означает wchar_t* GetSomeString; BSTR говорит вам, что использует семантику COM, но компилятор этого не знает. И эта семантика, которую вы называете SysFreeString.

_bstr_t::_bstr_t( wchar_t* str ) копий str. Да, _bstr_t::~_bstr_t вызовет SysFreeString, но это будет сделано для копии. Вам нужно было позвонить SysFreeString на BSTR GetSomeString();.

Решение _bstr_t::_bstr_t( BSTR bstr , bool fCopy ) с fCopy=false. За MSDN:

Этот конструктор используется функциями-обертками в библиотеке типов заголовки для инкапсуляции и получения права собственности на BSTR, который возвращается методом интерфейса.

Для VARIANT см. _variant_t::_variant_t(VARIANT& varSrc, bool fCopy);. Та же идея.

...