본문 바로가기
개발

COM 인터페이스 포인터를 서로 다른 Apartment로 전달하기

by 솜씨제이 2007. 6. 27.
멀티쓰레드 환경에서 COM을 사용할 때 서로 다른 쓰레드 간에 인터페이스 포인터를 넘겨서 사용하는 경우가 있을 수 있습니다.  이 때 Apartment Threaded인 경우 문제가 생깁니다. 서로 다른 Apartment로 인터페이스 포인터를 넘겨야 하는데 문제가 발생하는 경우가 있습니다. 이런 경우 Global Interface Table(GIT)을 사용하면 됩니다.
다음은 MS 기술자료(http://support.microsoft.com/kb/601770/ko)에 나와 있는 GIT 사용 단계입니다.

1. GIT 인스턴스를 생성합니다.
IGlobalInterfaceTable *pGIT = NULL;
::CoCreateInstance (CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void**)&pGIT);

2. GIT에 인터페이스 포인터를 등록합니다.
DWORD dwCookie = 0;
pGIT->RegisterInterfaceInGlobal (pDisp, IID_IDispatch, &dwCookie);

3. 다른 Apartment에서 등록된 인터페이스 포인터를 가져옵니다.
IDispatch *pDisp2 = NULL;
pGIT->GetInterfaceFromGlobal (dwCookie, IID_IDispatch, (void**)&pDisp);

4. 등록되어 있는 인터페이스 포인터를 제거합니다.
pGIT->RevokeInterfaceFromGlobal (dwCookie);
pGIT->Release();

ATL을 사용한다면 다음과 같이 좀 더 간단히 사용할 수 있습니다.

1. GIT 스마트 포인터를 생성합니다.
CComGITPtr<IDispatch> git(pDisp);

2. 등록된 쿠키값을 가져옵니다.
DWORD dwCookie = 0;
dwCookie = git.Detach();

3. 다른 Apartment에서 등록된 인터페이스 포인터를 가져옵니다.
  CComGITPtr<IDispatch> git(dwCookie);
  git.CopyTo(&pDisp);

4. 등록된 인터페이스 포인터 제거는 스마트 포인터가 해줍니다.

댓글