DirectX 9.0 의 소개 DirectX SDK 의 사용법 C 또는 C++ 에 의한 DirectX 프로그래밍 COM 의 사용법 COM 개체의 유효기간의 관리   [목차열람] [주소복사] [슬롯비우기]
COM 개체의 유효기간의 관리
 
Microsoft DirectX 9.0

COM 개체의 유효기간의 관리


개체가 생성 되면(자), 시스템은 필요한 메모리 리소스를 할당한다. 필요가 없어진 개체는, 파기할 필요가 있다. 시스템은, 그 메모리를 다른 목적으로 사용할 수 있다. C++ 개체에서는,newdelete 의 각 연산자를 사용해 개체의 유효기간을 직접 제어할 수 있다. 구성 요소 개체 모델 (COM)에서는, 개체를 직접 생성 또는 파기할 수 없다. 이것은, 같은 개체를 복수의 애플리케이션이 사용하고 있을 가능성이 있기 때문이다. 이러한 개체를 1 개의 애플리케이션이 파기 하면, 다른 애플리케이션에서는 높은 확률로 에러가 발생한다. COM 에서는,참조 카운트라고 하는 시스템을 사용해 개체의 유효기간을 제어하고 있다.

개체의 참조 카운트는, 그 개체의 몇개의 인터페이스가 요구된 회수를 나타낸다. 인터페이스가 요구될 때마다, 참조 카운트는 인크리먼트(increment) 된다. 필요가 없어진 인터페이스를 애플리케이션이릴리즈하면, 참조 카운트는 감소 된다. 개체는, 참조 카운트가 0 이 되지 않는 이상 메모리상에 보관 유지된다. 참조 카운트가 0 이 되면(자), 개체는 파기된다. 개체의 참조 카운트에 대해 알 필요는 없다. 개체의 인터페이스를 올바르게 취득해 릴리즈 하는 한, 개체의 유효기간은 적절히 제어된다.

중요  COM 프로그래밍에서는, 참조 카운트를 올바르게 처리하는 것이 매우 중요하다. 이 처리를 올바르게 실시하지 않으면 메모리 누수가 낳기 쉬워진다. COM 프로그래머가 가장 범하기 쉬운 미스의 1 개가, 인터페이스의 릴리즈 하는 것을 잊고이다. 인터페이스가 릴리즈 되지 않으면 참조 카운트가 언제까지나 0 이 되지 않고, 개체는 메모리에 계속 남는다.

참조 카운트의 인크리먼트(increment)와 감소

새로운 인터페이스 포인터를 얻어온다 여행에,IUnknown::AddRef 를 호출해 참조 카운트를 인크리먼트(increment) 할 필요가 있다. 다만, 보통, 애플리케이션으로 이 메서드를 호출할 필요는 없다. 개체 생성 메서드 또는 IUnknown::QueryInterface 를 호출해 인터페이스 포인터를 취득했을 경우, 개체는 자동적으로 참조 카운트를 인크리먼트(increment) 한다. 그러나, 기존의 포인터를 복사 하는 등, 그 외의 방법으로 인터페이스 포인터를 생성 했을 경우는,IUnknown::AddRef 를 명시적으로 호출할 필요가 있다. 이것을 실시하지 않으면 원의 인터페이스 포인터를 릴리즈 했을 때에, 그 포인터의 복사를 계속해 사용할 필요가 있어도, 개체가 파기되는 일이 있다.

참조 카운트를 인크리먼트(increment) 했던 것이 사용자일까 개체일까에 관계없이, 모든 인터페이스 포인터를 릴리즈 해야 한다. 인터페이스 포인터가 불필요하게 되었을 경우는,IUnknown::Release 를 호출해 참조 카운트를 감소 한다. 모든 인터페이스 포인터는 NULL 에 초기화해, 릴리즈시에 다시 NULL 로 설정하는 것이 일반적이다. 이것에 의해, 클린 업 코드로, 모든 인터페이스 코드를 테스트할 수 있다. NULL 가 아닌 포인터는 아직 액티브하고, 애플리케이션을 종료하기 전에 릴리즈 할 필요가 있다.

다음 코드는, 「COM 인터페이스의 사용법」으로 설명한 샘플을, 참조 카운트의 처리 방법을 나타내기 위해서(때문에) 확장한 것이다.

IDirectSoundBuffer9* pDSBPrimary = NULL;
IDirectSound3DListener9* pDSListener = NULL;
IDirectSound3DListener9* pDSListener2 = NULL;
...
//Create the object and obtain an additional interface.
//The object increments the reference count.

if(FAILED(hr = g_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL )))
  return hr;

if(FAILED(hr=pDSBPrimary->QueryInterface(IID_IDirectSound3DListener9,
                                        (LPVOID *) &pDSListener)))
  return hr;

//Make a copy of the IDirectSound3DListener9 interface pointer.
//Call AddRef to increment the reference count and to ensure that
//the object is not destroyed prematurely

pDSListener2 = pDSListener;
pDSListener2->AddRef();
...
//Cleanup code.Check to see if the pointers are still active.
//If they are, call Release to release the interface.

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

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

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


© 2002 Microsoft Corporation. All rights reserved.
↑TOP