CComObjectRootEx, classe
Cette classe fournit des méthodes pour gérer la gestion du nombre de références d’objets pour les objets non agrégés et non agrégés.
Syntaxe
template<class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
Paramètres
ThreadModel
Classe dont les méthodes implémentent le modèle de threading souhaité. Vous pouvez choisir explicitement le modèle de thread en définissant ThreadModel sur CComSingleThreadModel, CComMultiThreadModel ou CComMultiThreadModelNoCS. Vous pouvez accepter le modèle de thread par défaut du serveur en définissant ThreadModel sur CComObjectThreadModel ou CComGlobalsThreadModel.
Membres
Méthodes
Fonction | Description |
---|---|
CComObjectRootEx | Constructeur. |
InternalAddRef | Incrémente le nombre de références pour un objet non agrégé. |
InternalRelease | Décrémente le nombre de références pour un objet non agrégé. |
Verrouiller | Si le modèle de thread est multithread, obtient la propriété d’un objet de section critique. |
Déverrouiller | Si le modèle de thread est multithread, libère la propriété d’un objet de section critique. |
CComObjectRootBase, méthodes
Fonction | Description |
---|---|
FinalConstruct | Remplacez dans votre classe pour effectuer toute initialisation requise par votre objet. |
FinalRelease | Remplacez dans votre classe pour effectuer tout nettoyage requis par votre objet. |
OuterAddRef | Incrémente le nombre de références pour un objet agrégé. |
OuterQueryInterface | Délégués à l’extérieur IUnknown d’un objet agrégé. |
OuterRelease | Décrémente le nombre de références d’un objet agrégé. |
Fonctions statiques
Fonction | Description |
---|---|
InternalQueryInterface | Délégués à l’objet IUnknown non agrégé. |
ObjectMain | Appelé lors de l’initialisation et de l’arrêt du module pour les classes dérivées répertoriées dans le mappage d’objets. |
Données membres
Membre de données | Description |
---|---|
m_dwRef | Avec m_pOuterUnknown , partie d’une union. Utilisé lorsque l’objet n’est pas agrégé pour contenir le nombre de références et AddRef Release . |
m_pOuterUnknown | Avec m_dwRef , partie d’une union. Utilisé lorsque l’objet est agrégé pour contenir un pointeur vers l’inconnu externe. |
Notes
CComObjectRootEx
gère la gestion des nombres de références d’objets pour les objets non agrégés et non agrégés. Il contient le nombre de références d’objet si votre objet n’est pas agrégé et contient le pointeur vers l’inconnu externe si votre objet est agrégé. Pour les objets agrégés, CComObjectRootEx
les méthodes peuvent être utilisées pour gérer l’échec de la construction de l’objet interne et pour protéger l’objet externe contre la suppression lorsque les interfaces internes sont libérées ou que l’objet interne est supprimé.
Une classe qui implémente un serveur COM doit hériter ou CComObjectRoot CComObjectRootEx
.
Si votre définition de classe spécifie la macro DECLARE_POLY_AGGREGATABLE , ATL crée une instance de CComPolyObject<CYourClass>
quand IClassFactory::CreateInstance
elle est appelée. Lors de la création, la valeur de l’inconnu externe est vérifiée. S’il s’agit de NULL, IUnknown
est implémenté pour un objet non agrégé. Si l’inconnu externe n’est pas NULL, IUnknown
est implémenté pour un objet agrégé.
Si votre classe ne spécifie pas la macro DECLARE_POLY_AGGREGATABLE, ATL crée une instance d’objets CAggComObject<CYourClass>
agrégés ou une instance d’objets CComObject<CYourClass>
non agrégés.
L’avantage de l’utilisation CComPolyObject
est que vous évitez d’avoir à la fois CComAggObject
et CComObject
dans votre module pour gérer les cas agrégés et non agrégés. Un objet unique CComPolyObject
gère les deux cas. Par conséquent, une seule copie de la table virtuelle et une copie des fonctions existent dans votre module. Si votre vtable est volumineux, cela peut réduire considérablement la taille de votre module. Toutefois, si votre vtable est petit, l’utilisation CComPolyObject
peut entraîner une taille de module légèrement plus grande, car elle n’est pas optimisée pour un objet agrégé ou non agrégé, comme c’est le cas CComAggObject
et CComObject
.
Si votre objet est agrégé, IUnknown est implémenté par CComAggObject
ou CComPolyObject
. Ces classes délèguent QueryInterface
, AddRef
et Release
appellent ' CComObjectRootEx
s OuterQueryInterface
, OuterAddRef
et OuterRelease
pour transférer vers l’inconnu externe. En règle générale, vous remplacez CComObjectRootEx::FinalConstruct
dans votre classe pour créer des objets agrégés et remplacer CComObjectRootEx::FinalRelease
pour libérer tous les objets agrégés.
Si votre objet n’est pas agrégé, IUnknown
est implémenté par CComObject
ou CComPolyObject
. Dans ce cas, les appels à QueryInterface
, AddRef
et Release
sont délégués à CComObjectRootEx
's InternalQueryInterface
, InternalAddRef
et InternalRelease
pour effectuer les opérations réelles.
Spécifications
En-tête : atlcom.h
CComObjectRootEx ::CComObjectRootEx
Le constructeur initialise le nombre de références à 0.
CComObjectRootEx();
CComObjectRootEx ::FinalConstruct
Vous pouvez remplacer cette méthode dans votre classe dérivée pour effectuer toute initialisation requise pour votre objet.
HRESULT FinalConstruct();
Valeur de retour
Retournez S_OK sur la réussite ou l’une des valeurs HRESULT d’erreur standard.
Notes
Par défaut, CComObjectRootEx::FinalConstruct
retourne simplement S_OK.
Il existe des avantages pour effectuer l’initialisation au FinalConstruct
lieu du constructeur de votre classe :
Vous ne pouvez pas retourner un code d’état à partir d’un constructeur, mais vous pouvez renvoyer un HRESULT au moyen de la valeur de retour.
FinalConstruct
Lorsque des objets de votre classe sont créés à l’aide de la fabrique de classes standard fournie par ATL, cette valeur de retour est propagée au client COM, ce qui vous permet de leur fournir des informations d’erreur détaillées.Vous ne pouvez pas appeler des fonctions virtuelles par le biais du mécanisme de fonction virtuelle à partir du constructeur d’une classe. L’appel d’une fonction virtuelle à partir du constructeur d’une classe entraîne un appel résolu statiquement à la fonction telle qu’elle est définie à ce stade dans la hiérarchie d’héritage. Les appels à des fonctions virtuelles pures entraînent des erreurs d’éditeur de liens.
Votre classe n’est pas la classe la plus dérivée de la hiérarchie d’héritage. Elle s’appuie sur une classe dérivée fournie par ATL pour fournir certaines de ses fonctionnalités. Il existe une bonne chance que votre initialisation ait besoin d’utiliser les fonctionnalités fournies par cette classe (c’est certainement vrai lorsque les objets de votre classe doivent agréger d’autres objets), mais le constructeur de votre classe n’a aucun moyen d’accéder à ces fonctionnalités. Le code de construction de votre classe est exécuté avant que la classe la plus dérivée soit entièrement construite.
Toutefois,
FinalConstruct
elle est appelée immédiatement après la construction de la classe la plus dérivée, ce qui vous permet d’appeler des fonctions virtuelles et d’utiliser l’implémentation de comptage de référence fournie par ATL.
Exemple
En règle générale, remplacez cette méthode dans la classe dérivée pour CComObjectRootEx
créer des objets agrégés. Par exemple :
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.
Si la construction échoue, vous pouvez retourner une erreur. Vous pouvez également utiliser la macro DECLARE_PROTECT_FINAL_CONSTRUCT pour protéger votre objet externe de la suppression si, pendant la création, l’objet agrégé interne incrémente le nombre de références, puis décrémente le nombre à 0.
Voici un moyen classique de créer un agrégat :
Ajoutez un
IUnknown
pointeur à votre objet de classe et initialisez-le sur NULL dans le constructeur.Remplacez
FinalConstruct
la création de l’agrégat.Utilisez le
IUnknown
pointeur que vous avez défini comme paramètre pour la macro COM_INTERFACE_ENTRY_AGGREGATE .Remplacez
FinalRelease
le pointeur pour libérer leIUnknown
pointeur.
CComObjectRootEx ::FinalRelease
Vous pouvez remplacer cette méthode dans votre classe dérivée pour effectuer tout nettoyage requis pour votre objet.
void FinalRelease();
Notes
Par défaut, CComObjectRootEx::FinalRelease
ne fait rien.
L’exécution d’un nettoyage est FinalRelease
préférable à l’ajout de code au destructeur de votre classe, car l’objet est toujours entièrement construit au point où FinalRelease
il est appelé. Cela vous permet d’accéder en toute sécurité aux méthodes fournies par la classe la plus dérivée. Cela est particulièrement important pour libérer tous les objets agrégés avant la suppression.
CComObjectRootEx ::InternalAddRef
Incrémente le nombre de références d’un objet non agrégé de 1.
ULONG InternalAddRef();
Valeur de retour
Valeur qui peut être utile pour les diagnostics et les tests.
Notes
Si le modèle de thread est multithread, InterlockedIncrement
il est utilisé pour empêcher plusieurs threads de modifier le nombre de références en même temps.
CComObjectRootEx ::InternalQueryInterface
Récupère un pointeur vers l'interface demandée.
static HRESULT InternalQueryInterface(
void* pThis,
const _ATL_INTMAP_ENTRY* pEntries,
REFIID iid,
void** ppvObject);
Paramètres
pThis
[in] Pointeur vers l’objet qui contient la carte COM des interfaces exposées à QueryInterface
.
pEntries
[in] Pointeur vers la _ATL_INTMAP_ENTRY
structure qui accède à une carte d’interfaces disponibles.
iid
[in] GUID de l’interface demandée.
ppvObject
[out] Pointeur vers le pointeur d’interface spécifié dans iid ou NULL si l’interface est introuvable.
Valeur de retour
Une des valeurs HRESULT standard.
Notes
InternalQueryInterface
gère seulement des interfaces dans le tableau de mappage COM. Si votre objet est agrégé, InternalQueryInterface
ne délègue pas à l’inconnu externe. Vous pouvez entrer des interfaces dans la table de mappage COM avec la macro COM_INTERFACE_ENTRY ou l’une de ses variantes.
CComObjectRootEx ::InternalRelease
Décrémente le nombre de références d’un objet non agrégé par 1.
ULONG InternalRelease();
Valeur de retour
Dans les builds non debug et de débogage, cette fonction retourne une valeur qui peut être utile pour les diagnostics ou les tests. La valeur exacte retournée dépend de nombreux facteurs tels que le système d’exploitation utilisé et peut, ou non, être le nombre de références.
Notes
Si le modèle de thread est multithread, InterlockedDecrement
il est utilisé pour empêcher plusieurs threads de modifier le nombre de références en même temps.
CComObjectRootEx ::Lock
Si le modèle de thread est multithread, cette méthode appelle la fonction d’API Win32 EnterCriticalSection, qui attend que le thread puisse prendre possession de l’objet de section critique obtenu via un membre de données privé.
void Lock();
Notes
Une fois l’exécution du code protégé terminée, le thread doit appeler Unlock
pour libérer la propriété de la section critique.
Si le modèle de thread est monothread, cette méthode ne fait rien.
CComObjectRootEx ::m_dwRef
Partie d’une union qui accède à quatre octets de mémoire.
long m_dwRef;
Notes
Avec m_pOuterUnknown
, partie d’une union :
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
Si l’objet n’est pas agrégé, le nombre de références accessible AddRef
et Release
est stocké dans m_dwRef
. Si l’objet est agrégé, le pointeur vers l’inconnu externe est stocké dans m_pOuterUnknown.
CComObjectRootEx ::m_pOuterUnknown
Partie d’une union qui accède à quatre octets de mémoire.
IUnknown*
m_pOuterUnknown;
Notes
Avec m_dwRef
, partie d’une union :
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
Si l’objet est agrégé, le pointeur vers l’inconnu externe est stocké dans m_pOuterUnknown
. Si l’objet n’est pas agrégé, le nombre de références accessible AddRef
et Release
est stocké dans m_dwRef.
CComObjectRootEx ::ObjectMain
Pour chaque classe répertoriée dans le mappage d’objets, cette fonction est appelée une fois lorsque le module est initialisé et à nouveau lorsqu’il est arrêté.
static void WINAPI ObjectMain(bool bStarting);
Paramètres
bStarting
[out] La valeur est TRUE si la classe est initialisée ; sinon FALSE.
Notes
La valeur du paramètre bStarting indique si le module est initialisé ou arrêté. L’implémentation par défaut ne ObjectMain
fait rien, mais vous pouvez remplacer cette fonction dans votre classe pour initialiser ou nettoyer les ressources que vous souhaitez allouer pour la classe. Notez qu’elle ObjectMain
est appelée avant que toutes les instances de la classe soient demandées.
ObjectMain
est appelé à partir du point d’entrée de la DLL, de sorte que le type d’opération que la fonction de point d’entrée peut effectuer est restreint. Pour plus d’informations sur ces restrictions, consultez les DLL et le comportement de la bibliothèque d’exécution Visual C++ et DllMain.
Exemple
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
Incrémente le nombre de références de l’inconnu externe d’une agrégation.
ULONG OuterAddRef();
Valeur de retour
Valeur qui peut être utile pour les diagnostics et les tests.
CComObjectRootEx ::OuterQueryInterface
Récupère un pointeur indirect vers l’interface demandée.
HRESULT OuterQueryInterface(REFIID iid, void** ppvObject);
Paramètres
iid
[in] GUID de l’interface demandée.
ppvObject
[out] Pointeur vers le pointeur d’interface spécifié dans iid ou NULL si l’agrégation ne prend pas en charge l’interface.
Valeur de retour
Une des valeurs HRESULT standard.
CComObjectRootEx ::OuterRelease
Décrémente le nombre de références de l’inconnu externe d’une agrégation.
ULONG OuterRelease();
Valeur de retour
Dans les builds non debug, retourne toujours 0. Dans les builds de débogage, retourne une valeur qui peut être utile pour les diagnostics ou les tests.
CComObjectRootEx ::Unlock
Si le modèle de thread est multithread, cette méthode appelle la fonction API Win32 LeaveCriticalSection, qui libère la propriété de l’objet de section critique obtenu via un membre de données privé.
void Unlock();
Notes
Pour obtenir la propriété, le thread doit appeler Lock
. Chaque appel nécessite Lock
un appel correspondant pour Unlock
libérer la propriété de la section critique.
Si le modèle de thread est monothread, cette méthode ne fait rien.
Voir aussi
CComAggObject, classe
CComObject, classe
CComPolyObject, classe
Vue d’ensemble de la classe