Странный сбой при отладке деструктора COM-объекта - PullRequest
5 голосов
/ 22 августа 2011

Мое приложение представляет собой смесь кода C # и C ++.Модуль запуска, написанный на C #, загружается во время фазы инициализации модуля C ++ через механизм COM (объектная модель компонентов).Все работало правильно, пока я не решил добавить в C # часть службы wcf.Все вызовы службы wcf направляются в код C ++ с использованием COM.После добавления некоторых новых методов я заметил утечки памяти в окне вывода.Поэтому я добавил точку останова в дескриптор класса C ++, как видно на скриншоте.С этого момента странные вещи начали происходить.Когда программа достигает точки останова, она неожиданно падает.Первое, что странно, это то, что когда я запускаю программу без установленной точки останова, она любезно завершается.Вторая странная вещь заключается в том, что программа аварийно завершает работу, как если бы она работала без отладчика.После нажатия на кнопку «Открыть в отладчике» (или что-то вроде этого) я получаю сообщение об ошибке: «Программа уже открыта в отладчике».Нет сообщения в окне вывода, которое могло бы указать мне на источник ошибки, нет подозрительного кода.При добавлении окна сообщения в начало деструктора оно отображается на долю секунды, а затем закрывается все приложение (без добавления возможности пользователя читать то, что отображается в окне сообщения).Отчаянно ища любую подсказку.

PS Проблемы возникают только тогда, когда метод wcf был вызван хотя бы один раз.Не зависит, был ли поток программы в этом конкретном вызове направлен на уровень C ++ или нет.

enter image description here

enter image description here

Ответы [ 2 ]

1 голос
/ 22 августа 2011

При вызове C # из C ++ иногда сборщик мусора не вызывается должным образом до завершения программы. Попробуйте форсировать сборку мусора в конце кода C #.

0 голосов
/ 23 августа 2011

Разрешается следующим кодом:

public void Dispose()
{
    Marshal.Release(internal_interface_ptr);
    internal_interface_ptr = IntPtr.Zero;
    Marshal.ReleaseComObject(internal_interface);
    Marshal.ReleaseComObject(internal_interface);
    internal_interface = null;
} 

Кроме этого, в коде C ++ висела еще одна ссылка. Итак, чтобы сделать вывод, главной ошибкой с моей стороны было забыть явно освободить COM-объект в коде C #. Даже если сборщик мусора берет на себя задачу управления памятью, это не так для модулей, написанных на других языках программирования. COM-деструктор был вызван совсем недавно, когда из динамической библиотеки должна была быть выгружена определенная динамически связанная библиотека, что вызывало проблемы. Надеюсь, я объяснил это достаточно ясно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...