How to call an external component for COM client
COM hangs a separate EXE component that is more complicated than hidden a DLL component. The EXE component is not in the same process, and may not be in the same machine, but don't worry. Although you are writing it as a DLL to write your program. COM processes these details through its remote architecture, which typically contains Remote Procedure Call (RPC).
In RPC, the client program calls a special DLL, an agent (Proxy), proxy sends data flow to the residual root (STUB), and STUB is in a DLL of the component process. When the client calls a component method, Proxy sends a message to the component program to inform Stub, which is in the hidden Windows window. This mechanism for converting data parameters accepted and transmitted is called Marshal.
If you use a standard interface (these interfaces have been defined by Microsoft), such as iClassFactory and IPERSIST (this interface we haven't seen, but if you check the COM's curing (persistence) you will see), proxy and stub The code is used to perform Marshal, it has Windows OLE32 DLL. If you create a kind of your own interface, such as Imotion and Ivisual, then you will need to write your own proxy and stub. Write the Proxy and Stub classes, which contain your own interface with IDL (Interface Definition Language), and compiling these code, fortunately, these have been implemented by the MIDL (Microsoft Interface Definition "compiler.
Below is a pseudo code interactively interact with the EXE client, comparing it and the DLL version above, pay attention to the client's call is exactly consistent.
Client clsid clsid; iClassFactory * PCLF; IUNKNOWN * PUNK; Coinitialize (NULL); // Initialize COM CLSIDFROMPROGID ("ComponentName", & clsid);
COM COM looks for "ComponentName" class ID through the registry
Client CogetClassObject (CLSID, CLSCTX_LOCAL_SERVER, NULL, IID_ICLASSFAACTORY, (VOID **) & PCLF);
The COM COM uses class ID in memory (if the EXE component is not loaded, or we need another instance) {COM's file name COM from the registration table CoM load EXE component}
EXE Component if (already loaded) {Global Factory object is built into initInstance called (only for MFC) Coinitialize (null); for Each Factory object {CoregisterClassObject (...); return icsfactory * pointer to com}}
COM COM Returns the requested interface pointer to the client program (the client's pointer is not the same as the components interface)
Client PCLF-> CreateInstance (NULL, IID_IUNKNOWN, (VOID **) & PUNK);
The CreateInstance method for EXE Component Class Factory is called (via MARSHAL conversion Direct access) Build "ComponentName" class object indirectly returns the requesting interface pointer
Client PCLF-> Release (); punk-> release ();
Exe Component Annotation Annotation The Release Function IF (Reference Count == 0) {Object is self-destruction} if (all objects are released) {Components Self-exit} Client Couninitialize (); // Prepare to exit
COM COM call release to release all customer programs not released objects
Exe Component Components Exit
Com COM releases all resources
The Client client exits as you can see, COM plays a very important role between the client and components. COM will register a series of Class Factory in the called EXE component in memory, but it does not log the custom COM object, not as CsPaceShip. Customizing COM is responsible for self-destruction by addRef / Release mechanism to update the reference count. When the client exits, COM will complete these operations. If the client program is used, the processes are processed. COM will listen in communication and track the reference count of each object. When the client exits, COM will disconnect the connection to the component. Under certain circumstances, it will cause the component to release yourself, but do not rely on these behaviors to complete this work. Before exiting, make sure your client program releases all interface pointers.
Next: The MFC Interface Macros