Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Cualquier proceso que utilice COM debe inicializar y desinicializar la biblioteca COM. Además de ser una especificación, COM también implementa algunos servicios importantes en esta biblioteca. Se proporciona como un conjunto de archivos DLL y EXE (principalmente Ole32.dll y Rpcss.exe) en Microsoft Windows, la biblioteca COM incluye lo siguiente:
Un pequeño número de funciones fundamentales que facilitan la creación de aplicaciones COM, tanto cliente como servidor. Para los clientes, COM proporciona funciones básicas para crear objetos. En el caso de los servidores, COM proporciona los medios para exponer sus objetos.
Servicios de localizador de implementación a través de los cuales COM determina, a partir de un identificador de clase único (CLSID), que servidor implementa esa clase y dónde se encuentra ese servidor. Este servicio admite un nivel de indirección, normalmente un registro del sistema, entre la identidad de una clase de objeto y el empaquetado de la implementación, de modo que los clientes no dependan del empaquetado, ya que este puede cambiar en el futuro.
Llamadas transparentes a procedimientos remotos cuando un objeto se ejecuta en un servidor local o remoto.
Mecanismo estándar para permitir que una aplicación controle cómo se asigna la memoria dentro de su proceso, especialmente la memoria que debe pasarse entre objetos de cooperación para que se pueda liberar correctamente.
Para usar servicios COM básicos, todos los subprocesos COM de ejecución en clientes y servidores fuera de proceso deben llamar a la función CoInitialize o CoInitializeEx antes de llamar a cualquier otra función COM, excepto las llamadas de asignación de memoria. CoInitializeEx sustituye a la otra función, añadiendo un parámetro que permite especificar el modelo de subprocesos del hilo: apartment-threaded o free-threaded. Una llamada a CoInitialize simplemente establece el modelo de subprocesos en apartment-threaded.
Las aplicaciones de documentos compuestos OLE llaman a la función OleInitialize , que llama a CoInitializeEx y también realiza alguna inicialización necesaria para documentos compuestos. Por lo tanto, los subprocesos que llaman a OleInitialize no pueden ser subprocesos libres. Para obtener información sobre los subprocesos en clientes y servidores, consulte Procesos, subprocesos y apartamentos.
Los servidores en proceso no llaman a las funciones de inicialización porque se cargan en un proceso que ya lo ha hecho. Como resultado, los servidores en proceso deben establecer su modelo de subprocesos en el Registro, bajo la clave InprocServer32. Para obtener información detallada sobre los problemas de subprocesos en servidores en proceso, consulte Problemas de subprocesos en servidores en proceso.
También es importante desinicializar la biblioteca. Para cada llamada a CoInitialize o CoInitializeEx, debe haber una llamada correspondiente a CoUninitialize. Para cada llamada a OleInitialize, debe haber una llamada correspondiente a OleUninitialize.
Los servidores en proceso pueden dar por hecho que el proceso en el que se están cargando ya ha realizado estos pasos.
Importante
Todos los subprocesos que usen COM deben llamar CoInitializeEx antes de llamar a cualquier otra función COM. Este es el error de inicialización COM más común: llamar a CoCreateInstance u otras API COM en un subproceso que no se haya inicializado producirá un error CO_E_NOTINITIALIZED (0x800401F0).
Tip
Patrón recomendado: utilice un guard RAII para garantizar la desinicialización:
#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 ...
Si wil no está disponible, llame CoUninitialize() manualmente: cada llamada correcta CoInitializeEx debe emparejarse exactamente con una CoUninitialize llamada:
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) return hr;
// ... use COM ...
CoUninitialize();
Importante
Errores comunes:
- Llamar a funciones COM sin inicializar COM en el subproceso actual.
- Llamadas
CoInitializeEx/CoUninitializeno coincidentes (cada inicialización correcta requiere exactamente una desinicialización). - Mezcla de modelos de apartamento en el mismo hilo (llamar a
CoInitializeExcon un modelo diferente al de una llamada anterior correcta devuelveRPC_E_CHANGED_MODE).
Temas relacionados
-
The Component Object Model [Modelo de objetos componentes (COM)]