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.
Qualquer processo que use COM deve inicializar e desinicializar a biblioteca COM. Além de ser uma especificação, COM também implementa alguns serviços importantes nesta biblioteca. Fornecido como um conjunto de DLLs e EXEs (principalmente Ole32.dll e Rpcss.exe) no Microsoft Windows, a biblioteca COM inclui o seguinte:
Um pequeno número de funções fundamentais que facilitam a criação de aplicações COM, tanto cliente como servidor. Para os clientes, COM fornece funções básicas para a criação de objetos. Para os servidores, a COM fornece os meios de expor seus objetos.
Serviços de localizador de implementação através dos quais o COM determina, a partir de um identificador de classe exclusivo (CLSID), qual servidor implementa essa classe e onde esse servidor está localizado. Este serviço inclui suporte para um nível de indireção, geralmente um registro do sistema, entre a identidade de uma classe de objeto e o empacotamento da implementação para que os clientes sejam independentes do empacotamento, o que pode mudar no futuro.
Chamadas de procedimento remoto transparentes quando um objeto está sendo executado em um servidor local ou remoto.
Um mecanismo padrão para permitir que um aplicativo controle como a memória é alocada dentro de seu processo, particularmente a memória que precisa ser passada entre objetos cooperantes para que possa ser liberada corretamente.
Para usar serviços COM básicos, todos os threads de execução COM em clientes e servidores fora de processo devem chamar a função CoInitialize ou a função CoInitializeEx antes de chamar qualquer outra função COM, com exceção das chamadas de alocação de memória. CoInitializeEx substitui a outra função, adicionando um parâmetro que permite especificar o modelo de threading do thread: apartment-threaded ou free-threaded. Uma chamada para CoInitialize simplesmente define o modelo de threading como apartment-threaded.
Os aplicativos de documentos compostos OLE chamam a funçãoOleInitialize, que chama CoInitializeEx e também faz algumas inicializações necessárias para documentos compostos. Portanto, threads que chamam OleInitialize não podem ser encadeados livremente. Para obter informações sobre threading em clientes e servidores, consulte Processes, Threads e Apartments.
Os servidores em processo não chamam as funções de inicialização porque elas estão sendo carregadas em um processo que já fez isso. Como resultado, os servidores em processo devem definir o seu modelo de thread no registo sob a chave InprocServer32. Para obter informações detalhadas sobre problemas de threading em servidores em processo, consulte In-Process Server Threading Issues.
Também é importante desinicializar a biblioteca. Para cada chamada para CoInitialize ou CoInitializeEx, deve haver uma chamada correspondente para CoUninitialize. Para cada chamada para OleInitialize, deve haver uma chamada correspondente para OleUninitialize.
Os servidores em processo podem presumir que o processo no qual estão sendo carregados já executou essas etapas.
Importante
Cada thread que usa COM deve chamar CoInitializeEx antes de chamar qualquer outra função COM. Este é o erro mais comum de inicialização do COM — chamadas CoCreateInstance ou outras APIs COM num thread que não foi inicializado falham com CO_E_NOTINITIALIZED (0x800401F0).
Tip
Padrão recomendado — use um protetor RAII para garantir a desinicialização:
#include <wil/com.h> // Windows Implementation Libraries
// wil::unique_couninitialize_call calls CoUninitialize automatically on scope exit
auto comInit = wil::CoInitializeEx(COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
// ... use COM — CoUninitialize is called when comInit goes out of scope,
// even if an exception is thrown ...
Se o wil não estiver disponível, chame CoUninitialize() manualmente — cada chamada bem-sucedida a CoInitializeEx deve corresponder a exatamente uma chamada a CoUninitialize:
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) return hr;
// ... use COM ...
CoUninitialize();
Importante
Erros comuns:
- Chamar funções COM sem inicializar o COM no thread atual.
- Chamadas
CoInitializeEx/CoUninitializeincompatíveis (cada inicialização bem-sucedida requer exatamente um uninit). - Misturar modelos de apartment na mesma thread (chamar
CoInitializeExcom um modelo diferente do de uma chamada anterior bem-sucedida devolveRPC_E_CHANGED_MODE).
Tópicos relacionados