CComObjectRootEx 클래스
이 클래스는 집계되지 않은 개체와 집계된 개체 모두에 대한 개체 참조 개수 관리를 처리하는 메서드를 제공합니다.
구문
template<class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
매개 변수
ThreadModel
메서드가 원하는 스레딩 모델을 구현하는 클래스입니다. ThreadModel을 CComSingleThreadModel, CComMultiThreadModel 또는 CComMultiThreadModelNoCS로 설정하여 스레딩 모델을 명시적으로 선택할 수 있습니다. ThreadModel을 CComObjectThreadModel 또는 CComGlobalsThreadModel로 설정하여 서버의 기본 스레드 모델을 수락할 수 있습니다.
멤버
메서드
함수 | 설명 |
---|---|
CComObjectRootEx | 생성자입니다. |
InternalAddRef | 집계되지 않은 개체에 대한 참조 수를 늘입니다. |
InternalRelease | 집계되지 않은 개체에 대한 참조 수를 줄입니다. |
잠금 | 스레드 모델이 다중 스레드인 경우 중요한 섹션 개체의 소유권을 얻습니다. |
Unlock | 스레드 모델이 다중 스레드인 경우 중요한 섹션 개체의 소유권을 해제합니다. |
CComObjectRootBase 메서드
함수 | 설명 |
---|---|
FinalConstruct | 개체에 필요한 초기화를 수행하도록 클래스에서 재정의합니다. |
FinalRelease | 개체에 필요한 정리를 수행하려면 클래스에서 재정의합니다. |
OuterAddRef | 집계된 개체에 대한 참조 수를 증분합니다. |
OuterQueryInterface | 집계된 개체의 외부 IUnknown 에 대리자입니다. |
OuterRelease | 집계된 개체에 대한 참조 수를 줄입니다. |
정적 함수
함수 | 설명 |
---|---|
InternalQueryInterface | IUnknown 집계되지 않은 개체의 대리자입니다. |
ObjectMain | 개체 맵에 나열된 파생 클래스에 대한 모듈 초기화 및 종료 중에 호출됩니다. |
데이터 멤버
데이터 멤버 | 설명 |
---|---|
m_dwRef | 와 함께 m_pOuterUnknown , 공용 구조체의 일부. 개체가 집계되지 않은 경우 참조 개수 AddRef 및 Release . |
m_pOuterUnknown | 와 함께 m_dwRef , 공용 구조체의 일부. 개체를 집계하여 알 수 없는 외부에 대한 포인터를 저장할 때 사용됩니다. |
설명
CComObjectRootEx
는 집계되지 않은 개체와 집계된 개체 모두에 대한 개체 참조 개수 관리를 처리합니다. 개체가 집계되지 않는 경우 개체 참조 수를 유지하고 개체가 집계되는 경우 알 수 없는 외부에 대한 포인터를 보유합니다. 집계된 개체 CComObjectRootEx
의 경우 메서드를 사용하여 내부 개체의 생성 실패를 처리하고 내부 인터페이스가 해제되거나 내부 개체가 삭제될 때 외부 개체가 삭제되지 않도록 보호할 수 있습니다.
COM 서버를 구현하는 클래스는 CComObjectRoot에서 CComObjectRootEx
상속해야 합니다.
클래스 정의가 DECLARE_POLY_AGGREGATABLE 매크로를 지정하는 경우 ATL은 호출되는 경우 IClassFactory::CreateInstance
의 CComPolyObject<CYourClass>
인스턴스를 만듭니다. 만드는 동안 알 수 없는 외부의 값을 확인합니다. NULL IUnknown
인 경우 집계되지 않은 개체에 대해 구현됩니다. 알 수 없는 외부가 NULL IUnknown
이 아니면 집계된 개체에 대해 구현됩니다.
클래스에서 DECLARE_POLY_AGGREGATABLE 매크로를 지정하지 않으면 ATL은 집계된 개체의 CAggComObject<CYourClass>
인스턴스 또는 집계되지 않은 개체의 CComObject<CYourClass>
인스턴스를 만듭니다.
사용 CComPolyObject
의 장점은 모듈에서 CComAggObject
집계된 사례와 CComObject
집계되지 않은 사례를 모두 처리하지 않도록 방지한다는 것입니다. 단일 CComPolyObject
개체는 두 경우를 모두 처리합니다. 따라서 vtable의 복사본 하나와 함수의 복사본 하나만 모듈에 존재합니다. vtable이 크면 모듈 크기를 크게 줄일 수 있습니다. 그러나 vtable이 작으면 집계된 개체나 집계되지 않은 개체에 대해 최적화되지 않으므로 모 CComPolyObject
듈 크기를 약간 더 크게 만들 수 있습니다 CComAggObject
CComObject
.
개체가 집계되면 IUnknown이 구현됩니다CComAggObject
.CComPolyObject
이러한 클래스는 대리QueryInterface
자 AddRef
및 Release
'sOuterQueryInterface
에 OuterAddRef
대한 CComObjectRootEx
호출 및 OuterRelease
알 수 없는 외부로 전달합니다. 일반적으로 클래스에서 재정 CComObjectRootEx::FinalConstruct
의하여 집계된 개체를 만들고 집계된 개체를 해제하도록 재정 CComObjectRootEx::FinalRelease
의합니다.
개체가 집계 IUnknown
되지 않은 경우 또는 에 의해 CComObject
CComPolyObject
구현됩니다. 이 경우 < a0/>를 QueryInterface
호출하고 Release
실제 작업을 수행하기 위해 CComObjectRootEx
's's InternalRelease
InternalQueryInterface
InternalAddRef
에 위임됩니다. AddRef
요구 사항
헤더: atlcom.h
CComObjectRootEx::CComObjectRootEx
생성자는 참조 수를 0으로 초기화합니다.
CComObjectRootEx();
CComObjectRootEx::FinalConstruct
파생 클래스에서 이 메서드를 재정의하여 개체에 필요한 초기화를 수행할 수 있습니다.
HRESULT FinalConstruct();
Return Value
성공 시 S_OK 반환하거나 표준 오류 HRESULT 값 중 하나를 반환합니다.
설명
기본적으로 단순히 CComObjectRootEx::FinalConstruct
S_OK 반환합니다.
클래스의 생성자가 아닌 초기화를 FinalConstruct
수행할 때는 다음과 같은 이점이 있습니다.
생성자에서 상태 코드를 반환할 수는 없지만 반환 값을 통해
FinalConstruct
HRESULT를 반환할 수 있습니다. ATL에서 제공하는 표준 클래스 팩터리를 사용하여 클래스의 개체를 만드는 경우 이 반환 값이 COM 클라이언트로 다시 전파되어 자세한 오류 정보를 제공할 수 있습니다.클래스의 생성자에서 가상 함수 메커니즘을 통해 가상 함수를 호출할 수 없습니다. 클래스의 생성자에서 가상 함수를 호출하면 상속 계층 구조의 해당 시점에 정의된 대로 함수에 대한 정적으로 확인된 호출이 발생합니다. 순수 가상 함수를 호출하면 링커 오류가 발생합니다.
클래스는 상속 계층 구조에서 가장 많이 파생된 클래스가 아니며 ATL에서 제공하는 파생 클래스를 사용하여 일부 기능을 제공합니다. 초기화에서 해당 클래스에서 제공하는 기능을 사용해야 할 가능성이 높지만(클래스의 개체가 다른 개체를 집계해야 하는 경우 확실히 해당) 클래스의 생성자는 해당 기능에 액세스할 방법이 없습니다. 클래스의 생성 코드는 가장 파생된 클래스가 완전히 생성되기 전에 실행됩니다.
그러나
FinalConstruct
가상 함수를 호출하고 ATL에서 제공하는 참조 계산 구현을 사용할 수 있도록 가장 파생된 클래스가 완전히 생성된 직후에 호출됩니다.
예시
일반적으로 집계된 개체를 만들기 위해 파생된 클래스에서 CComObjectRootEx
이 메서드를 재정의합니다. 예시:
class ATL_NO_VTABLE CMyAggObject :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyAggObject, &CLSID_MyAggObject>,
public IDispatchImpl<IMyAggObject, &IID_IMyAggObject, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
DECLARE_GET_CONTROLLING_UNKNOWN()
HRESULT FinalConstruct()
{
return CoCreateInstance(CLSID_MyCustomClass, GetControllingUnknown(),
CLSCTX_ALL, IID_IUnknown, (void**)&m_pMyCustomClass);
}
IMyCustomClass* m_pMyCustomClass;
// Remainder of class declaration omitted.
생성에 실패하면 오류를 반환할 수 있습니다. 또한 매크로 DECLARE_PROTECT_FINAL_CONSTRUCT 사용하여 내부 집계된 개체가 참조 수를 증분한 다음 개수를 0으로 줄이면 외부 개체가 삭제되지 않도록 보호할 수 있습니다.
집계를 만드는 일반적인 방법은 다음과 같습니다.
IUnknown
클래스 개체에 포인터를 추가하고 생성자에서 NULL로 초기화합니다.집계를 만들려면 재정
FinalConstruct
의합니다.IUnknown
COM_INTERFACE_ENTRY_AGGREGATE 매크로에 대한 매개 변수로 정의한 포인터를 사용합니다.포인터를 해제하려면 재정
FinalRelease
의합니다IUnknown
.
CComObjectRootEx::FinalRelease
개체에 필요한 정리를 수행하려면 파생 클래스에서 이 메서드를 재정의할 수 있습니다.
void FinalRelease();
설명
기본적으로 CComObjectRootEx::FinalRelease
아무 것도 수행하지 않습니다.
개체가 호출되는 지점에서 FinalRelease
완전히 생성되므로 정리 FinalRelease
를 수행하는 것이 클래스의 소멸자에게 코드를 추가하는 것이 좋습니다. 이렇게 하면 가장 파생된 클래스에서 제공하는 메서드에 안전하게 액세스할 수 있습니다. 이는 삭제하기 전에 집계된 개체를 해제하는 데 특히 중요합니다.
CComObjectRootEx::InternalAddRef
집계되지 않은 개체의 참조 수를 1씩 증가합니다.
ULONG InternalAddRef();
Return Value
진단 및 테스트에 유용할 수 있는 값입니다.
설명
스레드 모델이 다중 스레드 InterlockedIncrement
인 경우 둘 이상의 스레드가 동시에 참조 횟수를 변경하지 못하도록 하는 데 사용됩니다.
CComObjectRootEx::InternalQueryInterface
요청된 인터페이스에 대한 포인터를 검색합니다.
static HRESULT InternalQueryInterface(
void* pThis,
const _ATL_INTMAP_ENTRY* pEntries,
REFIID iid,
void** ppvObject);
매개 변수
pThis
[in] 에 노출된 인터페이스의 COM 맵을 포함하는 개체에 대한 QueryInterface
포인터입니다.
pEntries
[in] 사용 가능한 인터페이스의 _ATL_INTMAP_ENTRY
맵에 액세스하는 구조체에 대한 포인터입니다.
iid
[in] 요청되는 인터페이스의 GUID입니다.
ppvObject
[out] iid에 지정된 인터페이스 포인터에 대한 포인터이거나, 인터페이스를 찾을 수 없는 경우 NULL입니다.
Return Value
표준 HRESULT 값 중 하나입니다.
설명
InternalQueryInterface
에서는 COM 맵 테이블의 인터페이스만 처리됩니다. 개체가 집계된 InternalQueryInterface
경우 알 수 없는 외부에 위임하지 않습니다. 매크로 COM_INTERFACE_ENTRY 또는 변형 중 하나를 사용하여 COM 맵 테이블에 인터페이스를 입력할 수 있습니다.
CComObjectRootEx::InternalRelease
집계되지 않은 개체의 참조 수를 1로 줄입니다.
ULONG InternalRelease();
Return Value
디버그가 아닌 빌드와 디버그 빌드 모두에서 이 함수는 진단 또는 테스트에 유용할 수 있는 값을 반환합니다. 반환되는 정확한 값은 사용되는 운영 체제와 같은 여러 요인에 따라 달라지며 참조 개수일 수도 있고 그렇지 않을 수도 있습니다.
설명
스레드 모델이 다중 스레드 InterlockedDecrement
인 경우 둘 이상의 스레드가 동시에 참조 횟수를 변경하지 못하도록 하는 데 사용됩니다.
CComObjectRootEx::Lock
스레드 모델이 다중 스레드인 경우 이 메서드는 Win32 API 함수 EnterCriticalSection을 호출합니다. 이 함수는 스레드가 프라이빗 데이터 멤버를 통해 가져온 중요한 섹션 개체의 소유권을 가져올 때까지 기다립니다.
void Lock();
설명
보호된 코드 실행이 완료되면 스레드는 중요한 섹션의 소유권을 해제하기 위해 호출 Unlock
해야 합니다.
스레드 모델이 단일 스레드인 경우 이 메서드는 아무 작업도 수행하지 않습니다.
CComObjectRootEx::m_dwRef
4바이트의 메모리에 액세스하는 공용 구조체의 일부입니다.
long m_dwRef;
설명
공용 m_pOuterUnknown
구조체의 일부인 경우:
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
개체가 집계되지 않은 경우 액세스하여 저장m_dwRef
되는 AddRef
Release
참조 횟수입니다. 개체가 집계되면 알 수 없는 외부에 대한 포인터가 m_pOuterUnknown 저장됩니다.
CComObjectRootEx::m_pOuterUnknown
4바이트의 메모리에 액세스하는 공용 구조체의 일부입니다.
IUnknown*
m_pOuterUnknown;
설명
공용 m_dwRef
구조체의 일부인 경우:
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
개체가 집계되면 알 수 없는 외부에 대한 포인터가 저장 m_pOuterUnknown
됩니다. 개체가 집계되지 않으면 액세스한 AddRef
Release
참조 개수가 m_dwRef 저장됩니다.
CComObjectRootEx::ObjectMain
개체 맵에 나열된 각 클래스에 대해 이 함수는 모듈이 초기화될 때와 종료될 때 다시 한 번 호출됩니다.
static void WINAPI ObjectMain(bool bStarting);
매개 변수
bStarting
[out] 클래스가 초기화되는 경우 값은 TRUE입니다. 그렇지 않으면 FALSE입니다.
설명
bStarting 매개 변수의 값은 모듈이 초기화되고 있는지 또는 종료되는지를 나타냅니다. 기본 구현은 아무 작업도 수행하지 않지만 클래스에서 이 함수를 재정의 ObjectMain
하여 클래스에 할당하려는 리소스를 초기화하거나 정리할 수 있습니다. 클래스의 인스턴스가 ObjectMain
요청되기 전에 호출됩니다.
ObjectMain
는 DLL의 진입점에서 호출되므로 진입점 함수가 수행할 수 있는 작업 유형이 제한됩니다. 이러한 제한 사항에 대한 자세한 내용은 DLL 및 Visual C++ 런타임 라이브러리 동작 및 DllMain을 참조하세요.
예시
class ATL_NO_VTABLE CMyApp :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyApp, &CLSID_MyApp>,
public IMyApp
{
public:
CMyApp()
{
}
static void WINAPI ObjectMain(bool bStarting)
{
if (bStarting)
;// Perform custom initialization routines
else
;// Perform custom termination routines
}
// Remainder of class declaration omitted.
CComObjectRootEx::OuterAddRef
집계를 알 수 없는 외부의 참조 수를 증분합니다.
ULONG OuterAddRef();
Return Value
진단 및 테스트에 유용할 수 있는 값입니다.
CComObjectRootEx::OuterQueryInterface
요청된 인터페이스에 대한 간접 포인터를 검색합니다.
HRESULT OuterQueryInterface(REFIID iid, void** ppvObject);
매개 변수
iid
[in] 요청되는 인터페이스의 GUID입니다.
ppvObject
[out] iid에 지정된 인터페이스 포인터에 대한 포인터이거나, 집계가 인터페이스를 지원하지 않는 경우 NULL입니다.
Return Value
표준 HRESULT 값 중 하나입니다.
CComObjectRootEx::OuterRelease
집계를 알 수 없는 외부의 참조 수를 줄입니다.
ULONG OuterRelease();
Return Value
디버그가 아닌 빌드에서는 항상 0을 반환합니다. 디버그 빌드에서 진단 또는 테스트에 유용할 수 있는 값을 반환합니다.
CComObjectRootEx::Unlock
스레드 모델이 다중 스레드인 경우 이 메서드는 Win32 API 함수 LeaveCriticalSection을 호출합니다. 이 함수는 프라이빗 데이터 멤버를 통해 얻은 중요한 섹션 개체의 소유권을 해제합니다.
void Unlock();
설명
소유권을 얻으려면 스레드가 호출 Lock
해야 합니다. 각 호출에는 Lock
중요한 섹션의 소유권을 해제하기 위한 Unlock
해당 호출이 필요합니다.
스레드 모델이 단일 스레드인 경우 이 메서드는 아무 작업도 수행하지 않습니다.