Есть ли безопасный способ сохранить указатели членов на COM-объекты из другой библиотеки DLL в одиночном COM-объекте? - PullRequest
0 голосов
/ 05 февраля 2009

Недавно я столкнулся с проблемой с объектом COM, который использовал фабрику синглтон-классов и имел члены, которые были указателями на другие COM-объекты, реализованные в другой DLL, чем объект-одиночка.

Эти другие COM-объекты были созданы одноэлементным объектом, и это была единственная ссылка на них.

Поскольку одноэлементный объект никогда не уничтожается до тех пор, пока его модуль не выгружен, то, по-видимому, происходит то, что иногда в этот момент DLL, в которой были реализованы другие COM-объекты (члены синглтона), уже выгружалась, и в этом случае произойдет сбой, когда синглтон выпустит свои ссылки на эти объекты в своем деструкторе.

DLL, реализующая другие COM-объекты, знает, что имеются ссылки на объекты, и возвращает S_FALSE из метода DllCanUnloadNow.

Однако, похоже, это не мешает выгружать DLL всегда.

Существует ли какой-либо безопасный способ сохранить указатели на COM-объекты из другой библиотеки DLL в одиночном COM-объекте?

Ответы [ 4 ]

1 голос
/ 05 февраля 2009

Вы вполне можете страдать от "неправильного" порядка выгрузки модуля. См. Почему DLL выгружаются в «неправильном» порядке? для получения дополнительной информации.

0 голосов
/ 05 февраля 2009

Если Джефф Стонг прав, попробуйте одно из:

  • Не выпускайте объект COM (пусть он протекает).

  • Создание зависимости времени соединения (а не только времени выполнения) от DLL, которая содержит синглтон, до DLL, которая содержит COM-объект.

  • Скажите синглтону умереть и / или освободить COM-объект до того, как процесс начнет умирать и DLL начнут принудительно выгружаться.

0 голосов
/ 05 февраля 2009

Когда синглтон получает реализации интерфейсов COM, IUnknown :: AddRef должен вызываться при реализации указателей, когда они получены.

То же самое касается доступа к полям синглтона, которые содержат эти ссылки. Когда вы получите ссылку, вы должны вызвать IUnknown :: AddRef, а затем, когда закончите, вызвать IUnknown :: Release.

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

Вам следует также использовать шаблон CComPtr , чтобы помочь в подсчете ссылок:

http://msdn.microsoft.com/en-us/library/ezzw7k98(vs.80).aspx

Возможно, вы захотите взглянуть на правила подсчета ссылок, которых вы должны придерживаться:

http://msdn.microsoft.com/en-us/library/ms810016.aspx

Найдите раздел под названием «Правила подсчета ссылок»

0 голосов
/ 05 февраля 2009

Если у вас есть указатель (также известный как «держать ссылку») на COM-объект, то этот COM-объект не должен исчезнуть, пока вы не отпустите его.

Если COM-объект не был освобожден, библиотека DLL, в которой реализован его код, не должна выгружаться: см. DllCanUnloadNow .

...