COM интерфейс исчезает из ROT - PullRequest
2 голосов
/ 02 августа 2010

У меня есть два приложения, оба из которых я написал.AppA была написана на C ++ с использованием MFC.Во время запуска он регистрирует CSingleDocTemplate и создает документ.Документ предоставляет интерфейс COM и регистрируется в ROT:

LPUNKNOWN punk = GetInterface(&IID_Welder); // doesn't AddRef
  ::RegisterActiveObject(punk, CLSID_Interface, ACTIVEOBJECT_WEAK, &m_dwRegister);

AppA отзывает запись в ROT, когда она уничтожена:

if (m_dwRegister)
    ::RevokeActiveObject(m_dwRegister, NULL);

Деструктор вызывается только когда AppAпрекращается.

AppB написан на C # и является клиентом интерфейса, предоставляемого AppA:

private void Connect()
  {
  welderInterface = (Welder.Interface)Marshal.GetActiveObject("Welder.Interface");
  Marshal.GetIUnknownForObject(welderInterface);    // AddRef's it ...
  }</p>

<p>private void Disconnect()
  {
  if (welderInterface != null)
    {
    Marshal.ReleaseComObject(welderInterface);
    welderInterface = null;
    }
  }
(обработка ошибок для ясности опущена)

Это все работает отлично при первом запуске AppB послеAppA запущено;AppB может вызывать Connect и Disconnect так часто, как хочет, и использовать интерфейс между ними.Однако, если AppB завершает работу и запускается снова (AppA все еще работает), интерфейс больше не доступен - Marshal.GetActiveObject выдает исключение из MK_E_UNAVAILABLE.Единственный способ сделать интерфейс снова доступным - перезапустить AppA - не приемлемое решение!

Может кто-нибудь подсказать, как я могу это исправить?

Ответы [ 2 ]

4 голосов
/ 02 августа 2010
 ::RegisterActiveObject(punk, CLSID_Interface, ACTIVEOBJECT_WEAK, &m_dwRegister);

ACTIVEOBJECT_WEAK - это ваша проблема здесь.Из документов RegisterActiveObject:

Слабая регистрация сохраняет указатель на объект в таблице запущенных объектов, но не увеличивает счетчик ссылок.Следовательно, когда последнее внешнее соединение со слабо зарегистрированным объектом исчезает, OLE освобождает заглушку объекта, а сам объект больше не доступен.

Что именно происходит в вашей программе.Тривиально решить проблему с ACTIVEOBJECT_STRONG.

0 голосов
/ 02 августа 2010

Я нашел проблему. Интерфейс удалялся, когда AppB отключался, даже несмотря на то, что документ MFC, в котором он был реализован, был еще жив. Я довольно глубоко изучил код MFC и ничего не нашел, но это должно происходить где-то там.

Я добавил интерфейс в конструкторе doc и выпустил его в деструкторе, и проблема была решена.

...