Очистка COM-объекта - PullRequest
       11

Очистка COM-объекта

2 голосов
/ 25 февраля 2010

В чем разница между двумя строками кода ниже:

CComPtr< IInterface > m_interface;

IInterface* m_interface;

Я знаю, что CComPtr помогает устранить утечки памяти, но я получаю противоречивые результаты. При объявлении указателя с помощью CComPtr< IInterface > m_interface; и используя интерфейс в моем коде C #, ошибок нет, однако при использовании интерфейса в VC ++ я получаю необработанную ошибку исключения, даже если закомментирую создание экземпляра IInterface.

Я почти уверен, что проблема где-то здесь:

STDMETHODIMP CSomeClass::get_IClass(IClass** var)
{ 
      return m_class_var->QueryInterface(var);
}
STDMETHODIMP CSomeClass::putref_IClass(IClass* var)
{ 
     m_class_var = var;
     return S_OK;
}

Когда я объявляю указатель интерфейса с помощью: IInterface* m_interface; Я получаю ошибку RPC_E_SERVERFAULT при тестировании интерфейса в C # и вынужден явно вызывать GC.Collect (), чтобы избежать появления ошибки после создания нескольких объектов. При тестировании интерфейса в VC ++ ошибка постоянна, однако при ее возникновении возникает другая проблема. Если я закомментирую создание экземпляра IInterface, код работает нормально, однако, когда я пытаюсь создать экземпляр, я получаю ту же ошибку, что и раньше, просто неопределенную необработанную ошибку исключения. Что я здесь не так делаю?

Ответы [ 3 ]

2 голосов
/ 25 февраля 2010

CComPtr - это интеллектуальный указатель, предназначенный для правильной работы при использовании с идиомами COM.

Ваш код для get_IClass выглядит хорошо, но putref_IClass необходимо вызвать AddRef на IClass, так как вы его храните. Если вы используете CComPtr, это произойдет автоматически.

Вам нужно будет добавить больше информации о вашем необработанном исключении VC ++.

1 голос
/ 25 февраля 2010

IInstance* m_instance - простой указатель на объект IInstance. Вы должны сами управлять временем жизни этого указателя. Вы не new и delete COM-объекты, как обычные объекты. Вместо этого операционная система выделяет объект при вызове функции WINAPI CoCreateInstance:

// instantiate the CoClass which implements IInstance...
IInstance* instance = 0;
HRESULT hr = CoCreateInstance(__uuidof(mylibrary::MyCoClass), 0, CLSCTX_INPROC_SERVER, __uuidof(mylib::IInstance), &instance);

:   :

// We're done, so release the object...
instance->Release();
instance = 0;

Каждый COM-объект осуществляет подсчет ссылок. Когда последняя ссылка на объект была Release() ed, COM-объект сам разрушается.

Использование CComPtr<> упрощает управление временем жизни объектов COM. Это умный указатель, похожий по своей природе на std :: auto_ptr или Boost's shared_ptr, но он работает с COM-объектами. Обычно при использовании CComPtr вы вызываете функцию-член CreateInstance вместо вызова функции WINAPI, и вы не будете явно вызывать Release, когда закончите. Просто позвольте CComPtr выйти из области видимости, и когда вызывается его деструктор, он вызовет для вас Release:

void function()
{
  // instantiate the CoClass which implements IMyInterface...
  CComPtr<IInstance> instance;
  instance.CoCreateInstance(__uuidof(mylibrary::MyCoClass));

  :   :

  // We're done, so release the object...
  // dont have to do anything, it will be released when function() exits
}
0 голосов
/ 25 февраля 2010

CComPtr m_interface - это объект. В то время как IInterface * m_interface является указателем.

У первого будет вызываться деструктор, когда он выходит из области видимости, и я думаю (долгое время с тех пор, как я его использовал), он автоматически вызовет m_interface -> Release ().

Последний является указателем на интерфейс, и вам нужно управлять, когда вызывается m_interface-> Release ().

Можете ли вы подтвердить, что объект COM не освобождается перед доступом?

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