Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Observação
A Active Template Library (ATL) continua a ser suportada. No entanto, já não estamos a adicionar funcionalidades nem a atualizar a documentação.
Esta classe fornece métodos para gerir a contagem de referências de objetos tanto para objetos não agregados como agregados.
Sintaxe
template<class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
Parâmetros
ThreadModel
A classe cujos métodos implementam o modelo de threading desejado. Pode escolher explicitamente o modelo de threading definindo o ThreadModel para CComSingleThreadModel, CComMultiThreadModel, ou CComMultiThreadModelNoCS. Pode aceitar o modelo de thread predefinido do servidor definindo o ThreadModel para CComObjectThreadModel ou CComGlobalsThreadModel.
Membros
Methods
| Função | Description |
|---|---|
| CComObjectRootEx | Construtor. |
| InternoAddRef | Incrementa a contagem de referências para um objeto não agregado. |
| InternalRelease | Diminui a contagem de referência para um objeto não agregado. |
| Bloqueio | Se o modelo de thread for multithread, obtém a propriedade de um objeto de secção crítico. |
| Desbloquear | Se o modelo de thread for multithread, liberta-se a propriedade de um objeto de secção crítico. |
Métodos CComObjectRootBase
| Função | Description |
|---|---|
| FinalConstruct | Sobrescreve na tua classe para realizar qualquer inicialização exigida pelo teu objeto. |
| FinalLançamento | Anule a sua classe para realizar qualquer limpeza exigida pelo seu objeto. |
| OuterAddRef | Incrementa a contagem de referências para um objeto agregado. |
| OuterQueryInterface | Delega para o exterior IUnknown de um objeto agregado. |
| OuterRelease | Diminui a contagem de referência para um objeto agregado. |
Funções estáticas
| Função | Description |
|---|---|
| InternalQueryInterface | Delega para o IUnknown de um objeto não agregado. |
| ObjectMain | Chamado durante a inicialização e terminação do módulo para classes derivadas listadas no mapa de objetos. |
Membros de Dados
| Membro de dados | Description |
|---|---|
| m_dwRef | Com m_pOuterUnknown, parte de um sindicato. Usado quando o objeto não é agregado para conter a contagem de referência de AddRef e Release. |
| m_pOuterUnknown | Com m_dwRef, parte de um sindicato. Usado quando o objeto é agregado para conter um ponteiro para o desconhecido exterior. |
Observações
CComObjectRootEx gere a contagem de referências de objetos tanto para objetos não agregados como agregados. Ele mantém a contagem de referências do objeto se o seu objeto não estiver a ser agregado, e mantém o ponteiro para o desconhecido exterior se o seu objeto estiver a ser agregado. Para objetos agregados, CComObjectRootEx podem ser usados métodos para lidar com a falha do objeto interior na construção e para proteger o objeto exterior da eliminação quando as interfaces internas são libertadas ou o objeto interior é eliminado.
Uma classe que implementa um servidor COM deve herdar de CComObjectRootEx ou CComObjectRoot.
Se a sua definição de classe especificar a macro DECLARE_POLY_AGGREGATABLE , o ATL cria uma instância de CComPolyObject<CYourClass> quando IClassFactory::CreateInstance é chamado. Durante a criação, verifica-se o valor do desconhecido exterior. Se for NULL, IUnknown é implementado para um objeto não agregado. Se o desconhecido exterior não for NULL, IUnknown é implementado para um objeto agregado.
Se a sua classe não especificar o macro DECLARE_POLY_AGGREGATABLE, o ATL cria uma instância de CAggComObject<CYourClass> para objetos agregados ou uma instância de CComObject<CYourClass> para objetos não agregados.
A vantagem de usar CComPolyObject é que evitas ter ambos CComAggObject no CComObject módulo para lidar com os casos agregados e não agregados. Um único CComPolyObject objeto trata ambos os casos. Portanto, existem apenas uma cópia da vtable e uma cópia das funções no seu módulo. Se a sua vtable for grande, isso pode diminuir substancialmente o tamanho do seu módulo. No entanto, se a sua vtable for pequena, a utilização CComPolyObject pode resultar num tamanho ligeiramente maior do módulo porque não está otimizada para um objeto agregado ou não agregado, tal como são CComAggObject e CComObject.
Se o seu objeto for agregado, IUnknown é implementado por CComAggObject ou CComPolyObject. Estas classes delegam QueryInterface, AddRef, e Release chamam a CComObjectRootEx, , OuterQueryInterfaceOuterAddRef, e OuterRelease a encaminhar para o desconhecido exterior. Normalmente, sobrescreves CComObjectRootEx::FinalConstruct na tua classe para criar quaisquer objetos agregados, e CComObjectRootEx::FinalRelease sobreescreves para libertar quaisquer objetos agregados.
Se o seu objeto não for agregado, IUnknown é implementado por CComObject ou CComPolyObject. Neste caso, chamadas para QueryInterface, , e Release são delegadas a CComObjectRootEx, InternalAddRefInternalQueryInterface, e InternalRelease para realizar as AddRefoperações reais.
Requerimentos
Cabeçalho: atlcom.h
CComObjectRootEx::CComObjectRootEx
O construtor inicializa a contagem de referência para 0.
CComObjectRootEx();
CComObjectRootEx::FinalConstruct
Pode sobrescrever este método na sua classe derivada para realizar qualquer inicialização necessária para o seu objeto.
HRESULT FinalConstruct();
Valor de retorno
Devolve S_OK em caso de sucesso ou de um dos valores padrão de erro HRESULT.
Observações
Por defeito, CComObjectRootEx::FinalConstruct simplesmente devolve S_OK.
Existem vantagens em realizar a inicialização em FinalConstruct vez do construtor da sua classe:
Não pode devolver um código de estado de um construtor, mas pode devolver um HRESULT por meio do
FinalConstructvalor de retorno de . Quando objetos da sua classe estão a ser criados usando a fábrica de classes padrão fornecida pelo ATL, este valor de retorno é propagado de volta ao cliente COM, permitindo-lhe fornecer informações detalhadas de erro.Não se podem chamar funções virtuais através do mecanismo de funções virtuais a partir do construtor de uma classe. Chamar uma função virtual a partir do construtor de uma classe resulta numa chamada resolvida estaticamente à função tal como está definida nesse ponto da hierarquia de herança. Chamadas a funções puramente virtuais resultam em erros de linker.
A sua classe não é a mais derivada na hierarquia de herança — depende de uma classe derivada fornecida pelo ATL para fornecer alguma da sua funcionalidade. Há uma boa hipótese de a sua inicialização precisar de usar as funcionalidades fornecidas por essa classe (isto é certamente verdade quando os objetos da sua classe precisam de agregar outros objetos), mas o construtor na sua classe não tem forma de aceder a essas características. O código de construção da sua classe é executado antes de a classe mais derivada estar totalmente construída.
No entanto,
FinalConstructé chamado imediatamente após a classe mais derivada estar totalmente construída, permitindo chamar funções virtuais e usar a implementação de contagem de referências fornecida pelo ATL.
Example
Normalmente, sobrepõe-se este método na classe derivada de CComObjectRootEx para criar quaisquer objetos agregados. Por exemplo:
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.
Se a construção falhar, pode devolver um erro. Também pode usar o DECLARE_PROTECT_FINAL_CONSTRUCT macro para proteger o seu objeto exterior de ser eliminado se, durante a criação, o objeto agregado interno incrementar a contagem de referência e depois decrementá-la para 0.
Aqui está uma forma típica de criar um agregado:
Adiciona um
IUnknownponteiro ao teu objeto de classe e inicializa-o como NULL no construtor.Override
FinalConstructpara criar o agregado.Use o
IUnknownponteiro que definiu como parâmetro para a macro COM_INTERFACE_ENTRY_AGGREGATE .Override
FinalReleasepara libertar oIUnknownapontador.
CComObjectRootEx::FinalRelease
Pode sobrescrever este método na sua classe derivada para realizar qualquer limpeza necessária para o seu objeto.
void FinalRelease();
Observações
Por defeito, CComObjectRootEx::FinalRelease não faz nada.
Fazer limpeza em FinalRelease é preferível a adicionar código ao destruidor da sua classe, pois o objeto ainda está totalmente construído no ponto em que FinalRelease é chamado. Isto permite-lhe aceder de forma segura aos métodos fornecidos pela classe mais derivada. Isto é particularmente importante para libertar quaisquer objetos agregados antes da eliminação.
CComObjectRootEx::InternalAddRef
Incrementa a contagem de referência de um objeto não agregado em 1.
ULONG InternalAddRef();
Valor de retorno
Um valor que pode ser útil para diagnóstico e testes.
Observações
Se o modelo de thread for multithread, InterlockedIncrement é usado para evitar que mais do que uma thread altere a contagem de referências ao mesmo tempo.
CComObjectRootEx::InternalQueryInterface
Recupera um ponteiro para a interface solicitada.
static HRESULT InternalQueryInterface(
void* pThis,
const _ATL_INTMAP_ENTRY* pEntries,
REFIID iid,
void** ppvObject);
Parâmetros
pThis
[dentro] Um apontador para o objeto que contém o mapa COM das interfaces expostas a QueryInterface.
pEntradas
[dentro] Um apontador para a _ATL_INTMAP_ENTRY estrutura que acede a um mapa das interfaces disponíveis.
IID
[dentro] O GUID da interface a ser solicitada.
ppvObject
[fora] Um ponteiro para o ponteiro da interface especificado no iid, ou NULL se a interface não for encontrada.
Valor de retorno
Um dos valores padrão do HRESULT.
Observações
InternalQueryInterface apenas trata de interfaces na tabela de mapas COM. Se o seu objeto for agregado, InternalQueryInterface não delega ao desconhecido exterior. Pode introduzir interfaces na tabela de mapas COM com a COM_INTERFACE_ENTRY macro ou uma das suas variantes.
CComObjectRootEx::InternalRelease
Diminui a contagem de referência de um objeto não agregado por 1.
ULONG InternalRelease();
Valor de retorno
Tanto em compilações sem depuração como em compilações de depuração, esta função devolve um valor que pode ser útil para diagnósticos ou testes. O valor exato devolvido depende de muitos fatores, como o sistema operativo utilizado, e pode, ou não, ser a contagem de referência.
Observações
Se o modelo de thread for multithread, InterlockedDecrement é usado para evitar que mais do que uma thread altere a contagem de referências ao mesmo tempo.
CComObjectRootEx::Lock
Se o modelo de thread for multithread, este método chama a função API Win32 EnterCriticalSection, que espera até que a thread possa assumir a propriedade do objeto crítico de secção obtido através de um membro privado de dados.
void Lock();
Observações
Quando o código protegido termina de ser executado, a thread deve chamar Unlock para libertar a propriedade da secção crítica.
Se o modelo de thread for single-thread, este método não faz nada.
CComObjectRootEx::m_dwRef
Parte de uma união que acede a quatro bytes de memória.
long m_dwRef;
Observações
Com m_pOuterUnknown, parte de uma união:
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
Se o objeto não for agregado, a contagem de referência acedida por AddRef e Release é armazenada em m_dwRef. Se o objeto for agregado, o ponteiro para o desconhecido exterior é armazenado em m_pOuterUnknown.
CComObjectRootEx::m_pOuterUnknown
Parte de uma união que acede a quatro bytes de memória.
IUnknown*
m_pOuterUnknown;
Observações
Com m_dwRef, parte de uma união:
union {
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
Se o objeto for agregado, o ponteiro para o desconhecido exterior é armazenado em m_pOuterUnknown. Se o objeto não for agregado, a contagem de referência acedida por AddRef e Release é armazenada em m_dwRef.
CComObjectRootEx::ObjectMain
Para cada classe listada no mapa de objetos, esta função é chamada uma vez quando o módulo é inicializado e outra quando é terminado.
static void WINAPI ObjectMain(bool bStarting);
Parâmetros
bInício
[fora] O valor é VERDADEIRO se a classe estiver a ser inicializada; caso contrário, FALSO.
Observações
O valor do parâmetro bStarting indica se o módulo está a ser inicializado ou terminado. A implementação padrão de ObjectMain não faz nada, mas podes sobrescrever esta função na tua classe para inicializar ou limpar recursos que queres alocar para a classe. Note que ObjectMain é chamado antes de qualquer instância da classe ser solicitada.
ObjectMain é chamado a partir do ponto de entrada da DLL, pelo que o tipo de operação que a função de entrada pode realizar é restringido. Para mais informações sobre estas restrições, veja DLLs e comportamento de bibliotecas em tempo de execução Visual C++ e DllMain.
Example
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
Incrementa a contagem de referência do desconhecido exterior de uma agregação.
ULONG OuterAddRef();
Valor de retorno
Um valor que pode ser útil para diagnóstico e testes.
CComObjectRootEx::OuterQueryInterface
Recupera um ponteiro indireto para a interface solicitada.
HRESULT OuterQueryInterface(REFIID iid, void** ppvObject);
Parâmetros
IID
[dentro] O GUID da interface a ser solicitada.
ppvObject
[fora] Um ponteiro para o ponteiro de interface especificado em iid, ou NULL se a agregação não suportar a interface.
Valor de retorno
Um dos valores padrão do HRESULT.
CComObjectRootEx::OuterRelease
Diminuição da contagem de referência do desconhecido exterior de uma agregação.
ULONG OuterRelease();
Valor de retorno
Em builds que não são de depuração, devolve sempre 0. Em compilações de depuração, devolve um valor que pode ser útil para diagnóstico ou testes.
CComObjectRootEx::Unlock
Se o modelo de thread for multithread, este método chama à função API Win32 LeaveCriticalSection, que liberta a propriedade do objeto crítico de secção obtido através de um membro privado de dados.
void Unlock();
Observações
Para obter a propriedade, o thread deve chamar Lock. Cada chamada para Lock requer uma chamada correspondente para Unlock libertar a propriedade da secção crítica.
Se o modelo de thread for single-thread, este método não faz nada.
Consulte também
Classe CComAggObject
Classe CComObject
Classe CComPolyObject
Visão geral da classe