CComObjectRootEx – třída
Tato třída poskytuje metody pro zpracování správy počtu odkazů na objekty pro neagregované i agregované objekty.
Syntaxe
template<class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
Parametry
ThreadModel
Třída, jejíž metody implementují požadovaný model vláken. Model vláken můžete explicitně zvolit nastavením ThreadModel na CComSingleThreadModel, CComMultiThreadModel nebo CComMultiThreadModelNoCS. Výchozí model vlákna serveru můžete přijmout nastavením ThreadModel na CComObjectThreadModel nebo CComGlobalsThreadModel.
Členové
Metody
Function | Popis |
---|---|
CComObjectRootEx | Konstruktor |
InternalAddRef | Zvýší počet odkazů pro neagregovaný objekt. |
InternalRelease | Sníží počet odkazů pro neagregovaný objekt. |
Uzamknout | Pokud je model vlákna vícevláknový, získá vlastnictví kritického objektu oddílu. |
Odemknout | Pokud je model vlákna vícevláknový, uvolní vlastnictví kritického objektu oddílu. |
CComObjectRootBase – metody
Function | Popis |
---|---|
FinalConstruct | Přepište ve třídě, aby se provedla jakákoli inicializace vyžadovaná objektem. |
FinalRelease | Přepište ve třídě, aby se provedlo vyčištění požadované objektem. |
OuterAddRef | Zvýší počet odkazů pro agregovaný objekt. |
OuterQueryInterface | Deleguje na vnější část IUnknown agregovaného objektu. |
Vnější verze | Sníží počet odkazů pro agregovaný objekt. |
Statické funkce
Function | Popis |
---|---|
InternalQueryInterface | Deleguje na IUnknown neagregovaný objekt. |
ObjectMain | Volá se během inicializace a ukončení modulu pro odvozené třídy uvedené v mapě objektu. |
Datové členy
Datový člen | Popis |
---|---|
m_dwRef | S m_pOuterUnknown , součástí sjednocení. Používá se, pokud objekt není agregován k uložení referenčního AddRef počtu a Release . |
m_pOuterUnknown | S m_dwRef , součástí sjednocení. Používá se při agregaci objektu pro uložení ukazatele na vnější neznámý objekt. |
Poznámky
CComObjectRootEx
zpracovává správu počtu odkazů na objekty pro neagregované i agregované objekty. Obsahuje počet odkazů na objekt, pokud objekt není agregován, a uchovává ukazatel na vnější neznámý objekt, pokud je objekt agregován. U agregovaných objektů CComObjectRootEx
lze metody použít ke zpracování selhání vnitřního objektu k vytvoření a k ochraně vnějšího objektu před odstraněním při uvolnění vnitřních rozhraní nebo odstranění vnitřního objektu.
Třída, která implementuje server COM musí dědit z CComObjectRootEx
nebo CComObjectRoot.
Pokud definice třídy určuje DECLARE_POLY_AGGREGATABLE makro, ATL vytvoří instanci CComPolyObject<CYourClass>
, kdy IClassFactory::CreateInstance
je volána. Při vytváření se zkontroluje hodnota vnější neznámé hodnoty. Pokud má hodnotu NULL, IUnknown
implementuje se pro neagregovaný objekt. Pokud vnější neznámý není NULL, IUnknown
je implementováno pro agregovaný objekt.
Pokud vaše třída neurčí DECLARE_POLY_AGGREGATABLE makro, ATL vytvoří instanci CAggComObject<CYourClass>
pro agregované objekty nebo instanci CComObject<CYourClass>
pro neagregované objekty.
Výhodou použití CComPolyObject
je, že se v modulu nemusíte zabývat CComAggObject
CComObject
agregovanými a neagregovanými případy. Jeden CComPolyObject
objekt zpracovává oba případy. Proto v modulu existuje pouze jedna kopie virtuální tabulky a jedna kopie funkcí. Pokud je vaše virtuální tabulka velká, může se tím podstatně zmenšit velikost modulu. Pokud je však tabulka vtable malá, může použití CComPolyObject
vést k mírně větší velikosti modulu, protože není optimalizovaná pro agregovaný nebo neagregovaný objekt, jak jsou CComAggObject
a CComObject
.
Pokud je objekt agregovaný, je IUnknown implementován pomocí CComAggObject
nebo CComPolyObject
. Tyto třídy delegují QueryInterface
, AddRef
a Release
volání CComObjectRootEx
' s OuterQueryInterface
, OuterAddRef
a OuterRelease
předat do vnější neznámé. Obvykle přepíšete CComObjectRootEx::FinalConstruct
ve své třídě, aby se vytvořily všechny agregované objekty, a přepsání CComObjectRootEx::FinalRelease
uvolnit všechny agregované objekty.
Pokud objekt není agregovaný, IUnknown
implementuje ho CComObject
nebo CComPolyObject
. V tomto případě jsou volání , QueryInterface
AddRef
a Release
jsou delegovány na CComObjectRootEx
' s InternalQueryInterface
, InternalAddRef
a InternalRelease
provádět skutečné operace.
Požadavky
Hlavička: atlcom.h
CComObjectRootEx::CComObjectRootEx
Konstruktor inicializuje počet odkazů na 0.
CComObjectRootEx();
CComObjectRootEx::FinalConstruct
Tuto metodu můžete v odvozené třídě přepsat, aby se provedla jakákoli inicializace požadovaná pro objekt.
HRESULT FinalConstruct();
Návratová hodnota
Vrátí S_OK při úspěchu nebo jedné ze standardních hodnot HRESULT chyby.
Poznámky
Ve výchozím nastavení CComObjectRootEx::FinalConstruct
jednoduše vrátí S_OK.
Provádění inicializace je FinalConstruct
výhodné místo konstruktoru třídy:
Stavový kód nelze vrátit z konstruktoru, ale hodnotu HRESULT můžete vrátit pomocí návratové
FinalConstruct
hodnoty. Když se objekty vaší třídy vytvářejí pomocí standardní továrny třídy poskytované ATL, tato návratová hodnota se rozšíří zpět do klienta COM, což vám umožní poskytnout je s podrobnými informacemi o chybách.Virtuální funkce nelze volat prostřednictvím mechanismu virtuální funkce z konstruktoru třídy. Volání virtuální funkce z konstruktoru třídy má za následek staticky vyřešené volání funkce, protože je definováno v tomto okamžiku v hierarchii dědičnosti. Volání čistě virtuálních funkcí způsobí chyby linkeru.
Vaše třída není nejvíce odvozenou třídou v hierarchii dědičnosti – spoléhá na odvozenou třídu, kterou atL poskytuje, aby poskytovala některé její funkce. Existuje dobrá šance, že vaše inicializace bude muset používat funkce poskytované touto třídou (to je jistě pravda, pokud objekty vaší třídy potřebují agregovat jiné objekty), ale konstruktor ve vaší třídě nemá žádný způsob, jak k těmto funkcím přistupovat. Kód konstrukce pro vaši třídu se provede před tím, než se úplně zkonstruuje odvozená třída.
Je
FinalConstruct
však volána okamžitě po nejvíce odvozené třídě je plně sestavena, takže můžete volat virtuální funkce a použít implementaci počítání odkazů poskytovanou ATL.
Příklad
Obvykle přepsat tuto metodu ve třídě odvozené z CComObjectRootEx
vytvořit všechny agregované objekty. Příklad:
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.
Pokud konstrukce selže, můžete vrátit chybu. Pomocí DECLARE_PROTECT_FINAL_CONSTRUCT makra můžete také chránit vnější objekt před odstraněním, pokud během vytváření interní agregovaný objekt zvýší počet odkazů a potom sníží počet na 0.
Tady je typický způsob vytvoření agregace:
IUnknown
Přidejte ukazatel na objekt třídy a inicializujete ho na hodnotu NULL v konstruktoru.Přepsání
FinalConstruct
pro vytvoření agregaceIUnknown
Použijte ukazatel, který jste definovali jako parametr na makro COM_INTERFACE_ENTRY_AGGREGATE.Přepsáním uvolněte
FinalRelease
IUnknown
ukazatel.
CComObjectRootEx::FinalRelease
Tuto metodu v odvozené třídě můžete přepsat, aby se provedlo vyčištění požadované pro objekt.
void FinalRelease();
Poznámky
Ve výchozím nastavení CComObjectRootEx::FinalRelease
nic nedělá.
Provádění čištění FinalRelease
je vhodnější přidat kód do destruktoru třídy, protože objekt je stále plně vytvořen v okamžiku, kdy FinalRelease
je volána. To vám umožní bezpečně přistupovat k metodám poskytovaným nejvíce odvozenou třídou. To je zvlášť důležité pro uvolnění všech agregovaných objektů před odstraněním.
CComObjectRootEx::InternalAddRef
Zvýší počet odkazů neagregovaného objektu o 1.
ULONG InternalAddRef();
Návratová hodnota
Hodnota, která může být užitečná pro diagnostiku a testování.
Poznámky
Pokud je model vlákna vícevláknový, InterlockedIncrement
slouží k zabránění změně počtu odkazů ve stejnou dobu více než jedno vlákno.
CComObjectRootEx::InternalQueryInterface
Načte ukazatel na požadované rozhraní.
static HRESULT InternalQueryInterface(
void* pThis,
const _ATL_INTMAP_ENTRY* pEntries,
REFIID iid,
void** ppvObject);
Parametry
PThis
[v] Ukazatel na objekt, který obsahuje mapu modelu COM rozhraní vystavených QueryInterface
.
PEntries
[v] Ukazatel na _ATL_INTMAP_ENTRY
strukturu, která přistupuje k mapě dostupných rozhraní.
iid
[v] Identifikátor GUID požadovaného rozhraní.
ppvObject
[ven] Ukazatel na ukazatel rozhraní zadaný v iid nebo NULL, pokud rozhraní není nalezeno.
Návratová hodnota
Jedna ze standardních hodnot HRESULT.
Poznámky
InternalQueryInterface
zpracovává pouze rozhraní v tabulce mapování modelu COM. Pokud je objekt agregovaný, InternalQueryInterface
neleguje na vnější neznámý objekt. Rozhraní můžete zadat do tabulky mapování modelu COM s makrem COM_INTERFACE_ENTRY nebo některou z jejích variant.
CComObjectRootEx::InternalRelease
Sníží počet odkazů neagregovaného objektu o 1.
ULONG InternalRelease();
Návratová hodnota
V sestaveních, které nejsou ladicí, i ladicí, vrátí tato funkce hodnotu, která může být užitečná pro diagnostiku nebo testování. Přesná vrácená hodnota závisí na mnoha faktorech, jako je použitý operační systém, a může nebo nemusí být referenčním počtem.
Poznámky
Pokud je model vlákna vícevláknový, InterlockedDecrement
slouží k zabránění změně počtu odkazů ve stejnou dobu více než jedno vlákno.
CComObjectRootEx::Lock
Pokud je model vlákna vícevláknový, tato metoda volá funkci rozhraní API Win32 EnterCriticalSection, která čeká, dokud vlákno nemůže převzít vlastnictví kritického objektu oddílu získaného prostřednictvím soukromého datového členu.
void Lock();
Poznámky
Po dokončení provádění chráněného kódu musí vlákno volat Unlock
uvolnění vlastnictví kritické části.
Pokud je model vlákna jednovláknový, tato metoda nedělá nic.
CComObjectRootEx::m_dwRef
Část sjednocení, která přistupuje ke čtyřbajtům paměti.
long m_dwRef;
Poznámky
S m_pOuterUnknown
částí sjednocení:
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
Pokud objekt není agregován, počet odkazů, ke které AddRef
přistupuje a Release
je uložen v m_dwRef
. Pokud je objekt agregován, je ukazatel na vnější neznámý uložen v m_pOuterUnknown.
CComObjectRootEx::m_pOuterUnknown
Část sjednocení, která přistupuje ke čtyřbajtům paměti.
IUnknown*
m_pOuterUnknown;
Poznámky
S m_dwRef
částí sjednocení:
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
Je-li objekt agregován, je ukazatel na vnější neznámý uložen v m_pOuterUnknown
. Pokud objekt není agregovaný, počet odkazů, ke které AddRef
se přistupuje, a Release
je uložen v m_dwRef.
CComObjectRootEx::ObjectMain
Pro každou třídu uvedenou v mapě objektu se tato funkce volá jednou při inicializaci modulu a znovu po ukončení.
static void WINAPI ObjectMain(bool bStarting);
Parametry
bStarting
[ven] Hodnota je TRUE, pokud je třída inicializována; jinak NEPRAVDA.
Poznámky
Hodnota parametru bStarting označuje, jestli se modul inicializuje nebo ukončuje. Výchozí implementace ObjectMain
nic nedělá, ale můžete tuto funkci ve třídě přepsat tak, aby inicializovala nebo vyčistila prostředky, které chcete přidělit pro třídu. Všimněte si, že ObjectMain
je volána před vyžádáním instancí třídy.
ObjectMain
je volána ze vstupního bodu knihovny DLL, takže typ operace, kterou může funkce vstupního bodu provést, je omezena. Další informace o těchtoomezeních
Příklad
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
Zvýší počet odkazů vnějšího neznámého agregace.
ULONG OuterAddRef();
Návratová hodnota
Hodnota, která může být užitečná pro diagnostiku a testování.
CComObjectRootEx::OuterQueryInterface
Načte nepřímý ukazatel na požadované rozhraní.
HRESULT OuterQueryInterface(REFIID iid, void** ppvObject);
Parametry
iid
[v] Identifikátor GUID požadovaného rozhraní.
ppvObject
[ven] Ukazatel na ukazatel rozhraní zadaný v iid nebo NULL, pokud agregace nepodporuje rozhraní.
Návratová hodnota
Jedna ze standardních hodnot HRESULT.
CComObjectRootEx::OuterRelease
Sníží počet odkazů vnějšího neznámého agregace.
ULONG OuterRelease();
Návratová hodnota
V neladit sestavení vždy vrátí hodnotu 0. V buildech ladění vrátí hodnotu, která může být užitečná pro diagnostiku nebo testování.
CComObjectRootEx::Unlock
Pokud je model vlákna vícevláknový, tato metoda volá funkci rozhraní API Win32 LeaveCriticalSection, která uvolní vlastnictví kritického objektu oddílu získaného prostřednictvím soukromého datového členu.
void Unlock();
Poznámky
Chcete-li získat vlastnictví, vlákno musí volat Lock
. Každé volání Lock
vyžaduje odpovídající volání k Unlock
uvolnění vlastnictví kritického oddílu.
Pokud je model vlákna jednovláknový, tato metoda nedělá nic.
Viz také
CComAggObject – třída
CComObject – třída
CComPolyObject – třída
Přehled třídy