Как получить FinalRelease для вызова при использовании GlobalInterfaceTable? - PullRequest
0 голосов
/ 04 января 2010

Я использую Visual Studio 2008 и создал проект ATL. Я добавил в проект простой объект ATL. Я хочу добавить свой объект в таблицу Global Interface Table при создании объекта, поэтому у меня есть следующий код в моем вызове FinalConstruct:

HRESULT res;
res = CoCreateInstance(GLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)mGit);
// res here is OK, mGit is not null
if(mGit != NULL)
{
   CComQIPtr<ISimObj> com_ptr = this;
   result = mGit->RegisterInterfaceInGlobal(com_ptr, __uuidof(ISimObj), &mGitCookie);
   // result is OK and mGitCookie is not null
}

Чтобы очистить, я добавил следующее к вызову FinalRelease:

if((mGit != NULL) && (mGitCookie != NULL))
{
   result = mGit->RevokeInterfaceFromGlobal(mGitCookie);
}

if(mGit != NULL)
{
   mGit->Release();
}

Затем я создал проект C #, добавил DLL в качестве ссылки и создал новый экземпляр SimObjClass. Я отлаживаю проект из проекта VC ++ и вижу, что вызывается FinalConstruct, и все устраивает. Затем я хочу удалить объект COM, поэтому я вызываю:

int res = Marshal.ReleaseComObject(mSimObjClass); // res is 0

из моего приложения на C #. Но при отладке приложения я заметил, что FinalRelease не вызывается. Читая далее, кажется, что RegisterInterfaceInGlobal будет увеличивать счетчик ссылок.

У меня вопрос: как правильно вызвать FinalRelease при использовании GIT? Я на самом деле не хочу создавать функцию, которая будет делать это вручную, так как это, кажется, побеждает цель FinalRelease. Есть идеи?

РЕДАКТИРОВАТЬ: Я должен также отметить, что если я удаляю вызов Register, FinalRelease вызывается, когда я вызываю ReleaseComObject.

1 Ответ

0 голосов
/ 04 января 2010

Да, вызов RRIG увеличивает счетчик ссылок. Вы не можете использовать FinalRelease, вам придется отозвать его, когда счетчик ссылок уменьшится до 1. Я не вижу очевидного способа сделать это в ATL, кроме как из CComObjectRootBase, поэтому вы можете написать свой собственный InternalRelease ( ).

Возможно, лучше сделать это явно, скажем, с помощью метода «Публикация и отзыв».

...