"COM principle and application" learning notes - the first part COM principle
Press: Article is highly summarized for COM principle, and it is recommended to learn COM. COM is destined to eliminate, but learning COM programming ideas is very meaningful.
Dreamtheater recommended must be good
"COM principle and application" learning notes - the first part COM principle
Savetime2k@yahoo.com
(This article is basically an extract from the "COM principle and application" book, copyright by author Pan Aimin all)
table of Contents
============================================================================================================================================================================================================= ==============================
⊙ Chapter 1 Overview
What COM is
COM objects and interfaces
CoM process model
COM reusability
⊙ Chapter 2 COM object model
Global unique identifier GUID
COM object
COM interface
Interface Description Language IDL
IUNKNOWN interface
Interface principle of COM object
⊙ Chapter 3 COM Realization
COM component registration information
Register your COM component
Class Factory and DllgetObjectClass functions
CogetherclassObject function
CoCreateInstance / CocreateInstanceex function
Initialization of COM library
COM library memory management
Component program loading and uninstall
COM library usage function
HRESULT type
⊙ Chapter 4 COM Features
Reusability: inclusive and aggregation
Process transparency (waiting for learning)
Safety (waiting for learning)
Multi-threaded feature (waiting for learning)
⊙ Chapter 5 Develops COM Apps with Visual C
Some header files provided by Win32 SDK
Some macros related to the COM interface
============================================================================================================================================================================================================= ==============================
Text
============================================================================================================================================================================================================= ============================== ⊙ first chapter outline
============================================================================================================================================================================================================= ==============================
What COM is
-------------------------------------------------- -----------------------------
COM is a component standard proposed by Microsoft, which not only defines a standard for interacting between component programs, but also provides the environment required for component program running. In the COM standard, a component program is also referred to as a module, which can be a dynamic link library, known as the in-process component; or an executable program (ie the exe program), Out-of-process component is called Out-of-Process Component. A component program can include one or more component objects because COM is a model that is the basic unit of the object, so when communication is communicating between the program and the program, the communication of communication should be a component object, also called a COM object, and the component program (Or COM program) is a code carrier that provides a COM object.
The COM object is different from the object concept in the general object (such as the C language), and the COM object is based on binary executable code level, and the object in the C and other languages are based on the source code level, so COM object is language-independent. This feature interacts with component objects developed by different programming languages.
-------------------------------------------------- -----------------------------
COM objects and interfaces
-------------------------------------------------- -----------------------------
Similar to the concept of objects in C , an object is an instance of a class (Class); the class is a set of related data and features a definition. Application (or another object) is called a customer, sometimes referred to as a user.
The interface is a set of logically related functions, which are also known as the interface member function. According to habits, the interface is prefixed in "i". The object provides customers with a variety of forms of service via interface member functions. In the COM model, the object itself is invisible to the customer, and only the client requests the service. Each interface is identified by a 128-bit global unique identifier (GLobal Unique Identifier). The client obtains the interface of the interface through the GUID, and then pass the interface pointer, the customer can call its corresponding member function.
Similar to the interface, each component is also identified by a 128-bit GUID, called a CLSID (Class Identifer, Class Identifier, or Class ID), using the CLSID identifier to ensure the uniqueness of the global scale. In fact, after the customer successfully creates an object, it gets a pointer to an object to an interface, because the COM object implements at least one interface (there is no meaning of the COM object without the interface), so the customer can call the interface to provide All services. According to the COM specification, a COM object can get any other interface of the object from an interface if a COM object is implemented. From this process, we can also see that customers and COM objects are only derived through the interface, and the object is just a set of interfaces for customers.
-------------------------------------------------- -----------------------------
CoM process model
-------------------------------------------------- -----------------------------
The service component object provided by COM has two process models in the implementation: internal objects and processes outside the process. If it is an object within the process, it runs in the client process space; if it is an external object, it runs the other process space on the machine or space in the remote machine.
Processing service program:
The service program is loaded into the customer's process space. In the Windows environment, the code usually implemented in the form of a dynamic connection library (DLL).
Local service procedure:
The service program is running on the same machine with the client program, and the service program is a separate application, usually it is an Exe file.
Remote service procedure:
The service runs on a machine different from the customer, which can be either a DLL module or an Exe file. If the remote service is implemented in a DLL, the remote machine creates a proxy process.
Although COM objects have different process models, this difference is transparent to the client program, so the customer program can use the component object whether or not, as long as the COM specification is followed. However, when implementing a COM object, it should also be carefully selected. The advantages of the process in the process are high efficiency, but component instability will cause customer process crashes, so components may endanger customers; (Savetime Note: here is a bit problem, if the component is unstable, the process exterior model will also have problems, maybe Because the components and customers in the process are relatively large, the possibility of conflicts is relatively large.) The advantages of the process exterior model are stability, the component process does not endanger the client program, and a component process can provide services for multiple clients. However, the processes have a larger cost, and the call is relatively low.
-------------------------------------------------- -----------------------------
COM reusability
-------------------------------------------------- ----------------------------- Because the COM standard is built in binary code level, the reusability and general of COM objects Object-oriented language such as the reuse process of objects in C is different. For the customer program of the COM object, it is only the service provided by the interface, which does not know the implementation process inside the object. Therefore, the reuse of the component object can be built in the behavior of the component object, not specific implementation. It is the key to establishing a reuse. COM uses two mechanisms to realize the reuse of objects. We assume that there are two COM objects, and the object 1 hopes to reuse the functions of the object 2, we refer to the object 1 as an external object, and the object 2 is called an internal object.
(1) Inclusive.
Object 1 contains object 2, when object 1 needs to use the function 2 function, it can simply perform the assignment object 2, although the object 1 and the object 2 support the same interface, but the object 1 is in the interface In fact, the implementation of the object 2 is actually called.
(2) The polymerization method.
Object 1 simply submits the interface of the object 2 to the customer, the object 1 does not implement the interface of the object 2, but it exposes the interface of the object 2 to the client, and the customer program does not know the internal object 2 exist.
============================================================================================================================================================================================================= ==============================
⊙ Chapter 2 COM object model
============================================================================================================================================================================================================= ==============================
Global unique identifier GUID
-------------------------------------------------- -----------------------------
The COM specification uses a 128-bit global unique identifier Guid to identify objects and interfaces, which is a random number and does not require specialized agencies to allocate and manage. Because the GUID is a random number, uniqueness is not absolute, but the possibility of the identifier is very small. In theory, if a machine generates 10000,000 GUID per second, it can be guaranteed (in probability) 3240 non-repetition).
GUID can be described in such a structure in C / C : typedef struct _guid
{
DWORD DATA1;
Word Data2;
Word data3;
Byte Data4 [8];
} Guid;
Example: {64BF4372-1007-B0AA-444553540000} You can define a guid as follows:
EXTERN "C" const guid clsid_myspellchecker =
{0x54BF0093, 0X1048, 0x399D,
{0xB0, 0xA3, 0x45, 0x33, 0x43, 0x90, 0x47, 0x47}};
Visual C provides two programs to generate the GUID: Uuidgen.exe (Command Line), and GUIDGEN.exe (dialog). The COM library provides the following API functions to generate GUID:
HRESULT COCREATEGUID (GUID * PGUID);
If you create a GUID success, the function returns S_OK, and the PGUID will point to the resulting GUID value.
-------------------------------------------------- -----------------------------
COM object
-------------------------------------------------- -----------------------------
In the COM specification, there is no strict definition of COM objects, but COM provides an object-oriented component model, and the COM component is provided to the customer's entity in an object form. The entity that interacts with the COM program is a COM object. It doesn't care about the name and location of the component model (ie, location transparency), but it must know that it is interacting with which COM object.
-------------------------------------------------- -----------------------------
COM interface
-------------------------------------------------- -----------------------------
As a result, the interface is a data structure containing a set of functions. By this group of data structures, the customer code can call the functionality of the component object. The interface defines a set of member functions, this group member function is all information exposed by component objects, and the client uses these functions to get the service of component objects.
Usually we refer to the interface function table as a virtual function table (VTABLE), pointing to the vTable pointer to PVTable. For an interface, its virtual function table is determined, so the number of member functions of the interface is unchanged, and the success of the member function is constant; for each member function, its parameters and The return value is also determined. In the definition of an interface, all of this must be determined at the binary level, no matter what language, as long as such memory structure description can be supported, the interface can be used.
Interface pointer ----> pvtable ----> Pointer function 1 -> | ---------- |
M_Data1 Pointer Function 2 -> | Object Implementation |
M_Data2 Pointer Function 3 -> | ------------ |
The first parameter of each interface member function is a pointer (= this) that points to the object instance, because the interface itself is not independent, it must exist on a COM object, so the pointer can provide an object instance Information, when called, the interface can know which COM object is operated. In the interface member function, the string variable must use the Unicode character pointer, the COM specification requires the use of Unicode characters, and the COM API function provided in the COM library also uses the Unicode characters. So if the ANSI character is used inside the component program, the conversion of two characters should be performed. Of course, in the case where the component program is established and the client program can be used, you can use your own defined parameter type as long as they are compatible with the parameter type that COM can identify.
Visual C provides two strings conversions:
Namespace _Com_UTIL {
BSTR ConvertStringTOBSTR (Const Char * PSRC) Throw (_COM_ERROR);
BSTR ConvertBSTRTSTRING (BSTR PSRC) Throw (_COM_ERROR);
}
BSTR is a double-byte width string that is the most common automated data type.
-------------------------------------------------- -----------------------------
Interface Description Language IDL
-------------------------------------------------- -----------------------------
The COM specification describes the description language of the COM interface based on the OSF DCE specification describing the remote call interface IDL (Interface Description Language, Interface Description Language). Interface Description Language provides a description method that does not depend on any language, so it can be a common language between component programs and client programs.
The IDL interface description language used by the COM specification is not only available to the COM interface, but also defines some common data types, or describes the custom data structure. For interface member functions, we can define the type of each parameter, input and output Features, and even support the array of variable lengths. IDL supports pointer type, very similar to C / C . E.g:
Interface idictionary
{
HRESULT Initialize ()
HRESULT LOADLIBRARY ([In] string;
HRESULT INSERTWORD ([in] string, [in] string);
HRESULT DeleteWord ([in] string);
HRESULT LOOKUPWORD ([in] string, [out] string *);
HRESULT RESTORELIBRARY ([in] string;
HRESULT FREELIBRARY ();
}
Microsoft Visual C provides a MIDL tool that can compile the IDL interface description file into a C / C compatible interface description header file (.h).
-------------------------------------------------- -----------------------------
IUNKNOWN interface
-------------------------------------------------- -----------------------------
IUNKNOWN IDL Definition:
Interface iunknown {
HRESULT QueryInterface ([in] refiid IID, [OUT] void ** PPV);
Ulong AddRef (Void);
Ulong Release (Void);
}
IUNKOWN C definition:
Class Iunknown
{
Virutal HRESULT _STDCALL QUERYINTERFACE (Const IID & IID, VOID ** PPV) = 0;
Virtual ulong _stdcall addref () = 0;
Virutal ulong _stdcall release () = 0;
}
-------------------------------------------------- -----------------------------
Interface principle of COM object
-------------------------------------------------- -----------------------------
The COM specification sets the following rules for the QueryInterface function:
1. For different interface pointers of the same object, the IUNKNOWN interface that the query must be identical. That is, the iUnknown interface pointer of each object is unique. Therefore, for two interface pointers, we can determine whether they point to the same object by determining whether the IUNKNOWN interface of the query is equal.
2. Interface is self-translocation. Querying an interface should be successful, such as:
Pidictionary-> queryInterface (IID_Dictionary, ...) should return S_OK.
3. Interface symmetry. If you query another interface pointer from an interface pointer, return from the second interface pointer to the first interface pointer must be successful, such as:
Pidictionary-> queryinterface (IID_SPELLCHECK, (Void **) & pispellcheck);
If you find success, then you will be successful from the PispellCheck to the IID_DICTIONARY interface.
4. Interface transfer property. If you query the second interface pointer from the first interface pointer, you can query the third interface pointer from the second interface pointer, you can query the first interface pointer from the third interface pointer.
5. Interface query time independence. If an interface pointer can be queried at a certain moment, then query the same interface pointer any time will be queried.
In short, no matter which interface we have, we can always reach any interface, and we can always return to the initial interface.
============================================================================================================================================================================================================= ==============================
⊙ Chapter 3 COM Realization
============================================================================================================================================================================================================= ============================= COM component registration information
-------------------------------------------------- -----------------------------
Information of all components on the current machine HKEY_CLASS_ROOT / CLSID
Process components HKEY_CLASS_ROOT / CLSID / GUID / INPROCSERVER32
Process Extractions HKEY_CLASS_ROOT / CLSID / GUID / LOCALRERVER32
Component belongs (CATID) HKEY_CLASS_ROOT / CLSID / GUID / IMPLEMENTED CATEGORIES
Configuration information of COM interface HKEY_CLASS_ROOT / Interface
Agent DLL / Store DLL HKEY_CLASS_ROOT / CLSID / GUID / Proxystubclsid
HKEY_CLASS_ROOT / CLSID / GUID / Proxystubclsid32
Type library information HKEY_CLASS_ROOT / TYPELIB
String Named Progid HKEY_CLASS_ROOT / (for example, "Comctl.TreeCtrl")
Component Guid HKEY_CLASS_ROOT / COMTRL.TREECONTROL / CLSID
Default version number hkey_class_root / comtrl.treeControl / Curver
(For example, curver = "comtrl.treectrl.1", then
HKEY_CLASS_ROOT / COMTRL.TREECONTROL.1 also exists)
Current Machine All Components Categories HKEY_CLASS_ROOT / COMPONENT CATEGORIES
COM provides two API functions CLSIDFROMPROGID and PROGIDFROMCLSID to convert Progid and CLSID.
If the COM component supports the same set of interfaces, they can be separated into the same class, and one component can be divided into multiple classes. For example, all automation objects support iDISPATCH interfaces, you can mean them into a class "Automation Objects". Category information is also described in a GUID called CACID. The main use of component categories is that customers can quickly discover specific types of component objects on the machine. Otherwise, all component objects must be checked, and put the component object into the memory instantiation, and then ask if it is necessary The interface, now you can save the query process now.
-------------------------------------------------- -----------------------------
Register your COM component
-------------------------------------------------- ---------------------------- Regsrv32.exe is used to register a process within a process, which calls the DLL DllRegisterServer and DllunRegisterServer functions Complete component Registration and logout operation of the program. If the operation successfully returns True, it will return false.
For process external components, the situation is slightly different, because it itself is an executable program, and it cannot provide an entry function for other programs. Therefore, in the COM specification, support from registered process external components must support two command line parameters / regserver and / unregserver to complete registration and logout operations. Command line parameter case is not related, and "/" can be replaced with "-". If the operation is successful, the program returns 0, otherwise, returning non-0 means failed.
-------------------------------------------------- -----------------------------
Class Factory and DllgetObjectClass functions
-------------------------------------------------- -----------------------------
Class Factory is a production base for COM objects. The COM library creates a COM object through a class factory; corresponding to each COM class, there is a class factory for the COM class object creation operation. The class is also a COM object, which supports a special interface iClassFactory:
Class iClassFactory: Public IUNKNOWN
{
Virtual HRESULT _STDCALL CREATEINSTANCE (IUNKNOWN * Punknownouter,
Const IID & IID, VOID ** PPV) = 0;
Virtual HRESULT _STDCALL LOCKSERVER (BOOL Block) = 0;
}
The CREATEINSTANCE member function is used to create a corresponding COM object. The first parameter PunkNOWNOUTER is used for the case where the object class is aggregated. It is typically set to null; the second parameter IID is the initial interface IID that the client should get after the object creation is completed; the third parameter PPV stores the returned interface pointer.
The LockServer member function is used to control the survival cycle of the component.
The class factory object is created by the DLL extraction function DllgetClassObject:
HRESULT DLLGETCLASSOBJECT (Const CLSID & CLSID, Const IID & IID, (Void **) PPV);
The first parameter of the DllgetClassObject function is the CLSID of the object to be created. Because a component may implement multiple COM object classes, it is necessary to specify a CLSID in the parameters of the DllgetClassObject function to create the correct Class Factory. The other two parameters IID and PPV respectively refer to the specified interface IID and the storage class interface pointer.
After receiving the instruction created by the object, it wants to call the DllgetClassObject function of the components within the process, create a class factory object, and return to the interface pointer of the class factory object. COM libraries or clients Once the interface pointers of the class is, they can create the corresponding COM objects via the iClassFactory member function CreateInstance.
-------------------------------------------------- ---------------------------- COGETCLASSOBJECT functions
-------------------------------------------------- -----------------------------
In the COM library, there are three APIs available for the creation of objects, which are CogetClassObject, CocreateInstnace, and CocreateInstanceex. Typically, the client program is called one of the created objects to complete the object, and returns the initial interface pointer of the object. The COM library and class is also interacting through these three functions.
HRESULT COGETCLASSOBJECT (Const CLSID & CLSID, DWORD DWCLSCONTEXT,
CoserverInfo * PServerInfo, Const IID & IID, (void **) PPV);
The COGETCLASSOBJECT function first finds a class factory that is specified by the CLSID, and then connects to the class factory object. If necessary, the CogetherClassObject function is loaded into the component code. If it is a component object within the process, CogetherClassObject calls the DllgetClassObject extraction function of the DLL module to pass the parameters CLSID, IID, and PPV to the DllgetClassObject function, and return to the interface pointer of the class factory object. Typically, IID is IclassFactory identifier IID_ICLASSFAACTORY. If the class factory object also supports other interfaces that can be used to create operations, other interface identifiers can also be used. For example, you can request an IClassFactory2 interface to verify the user's license when you are created. The iClassFactory2 interface is an extension to iClassFactory, which enhances the security of components creation.
Parameters dwclsContext Specify component categories, which can be specified as internal components, process external components, or processes within the process (similar to proxy objects similar to process external components, mainly for OLE technology). The parameters IID and PPV correspond to the parameters of DllgetClassObject, which are used to specify interface pointers for interface IIDs and storage classes. The parameter PServerInfo is used to create a remote object, and the NULL is set when the component object or the local process object is created in the process.
If the CogetClassObject function created class mill objects are in progress, the situation is much more complicated. First, the COGETCLASSObject function starts the component process, then waits until the component process registers the COM class objects that it supports to COM. So the COGETCLASSObject function returns the corresponding class factory information in COM. Therefore, the component process is started by the COM library (with command line parameters "/ Embedding"), it must register the supported COM class to the COM with the CoregisterClassObject function to create a COM object. When the process exits, you must call the CoreVokeclassObject function to notify COM that is no longer valid. The component program calls the CoregisterClassObject function and the CoreVokeClassObject function must be paired to ensure consistency of COM information.
-------------------------------------------------- -----------------------------
CoCreateInstance / CocreateInstanceex function ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
HRESULT COCREATEINSTANCE (Const CLSID & CLSID, IUNKNOWN * PUNKNOWNOUTER,
DWORD DWCLSCONTEXT, Const IID & IID, (void **) PPV);
CocreateInstance is a packaged auxiliary function that actually calls the CogetClassObject function in its internal actual. COCREATEINSTANCE The meaning of CLSID and DWclsContext consistent with the corresponding parameters of COGETClassObject, and the IID and PPV parameters of COGETEINSTANCE are different from COGETClassObject, one is the interface information of the object, one is the interface information of the class factory). The parameter PunkNownouter consistent with the corresponding parameters in the CreateInstance of the class factory interface, mainly for the case where the object is aggregated. The CocreateInstance function encapsulates the process of creating objects through the class factory, and the client program only specifies the CLSID of the object class and the interface pointer to the interface to be output, the client program can be deal with the class factory. CoCreateInstance can be implemented with the following code:
(Savetime Note: The application of the PPV pointer in the code below should be a void **)
HRESULT COCREATEINSTANCE (Const CLSID & CLSID, IUNKNOWN * PUNKNOWNOUTER,
DWORD DWCLSCONTEXT, Const IID & IID, VOID * PPV)
{
ICLASSFAACTORY * PCF;
HRESULT HR;
HR = COGETCLASSOBJECT (CLSID, DWCLSCONTEXT, NULL, IID_ICLASSFACTORY,
(void *) PCF);
IF (Failed (HR)) Return HR;
HR = PCF-> CreateInstance (PunkNownouter, IID, (Void *) PPV);
PFC-> Release ();
Return HR;
}
From this code, we can see that the CoCreateInstance function first creates a class factory object using the COGETCLASSObject function, and then creates a real COM object with the interface pointer of the obtained class factory object, and finally release the class object object and returned, so that the class Factory shield.
However, with COCREATEINSTANCE does not create objects on the remote machine, because when CogetClassObject is called, set the third parameter for specifying server information to NULL. If you want to create a remote object, you can use the CocreateInstance extension function CoCreateInstanceex:
HRESULT COCREATEINSTANCEEX (Const CLSID & CLSID, IUNKNOWN * PUNKNOWNOUTER,
DWORD DWCLSCONTEXT, COSERVERINFO * PSERVERINFO, DWORD DWCOUNT,
MULTI_QI * RGMULTIQI);
The first three parameters are the same as CocreateInstance. The PServerInfo is the same as the COGETCLASSOJBECT parameters. The last two parameters dwcount and RGMultiqi specify a structural array, which can be used to save multiple object interface pointers, the purpose is to get more An interface pointer to reduce frequent interactions between client programs and component programs, which is meaningful for remote objects in a network environment. -------------------------------------------------- -----------------------------
Initialization of COM library
-------------------------------------------------- -----------------------------
Before calling the function of the COM library, in order to make the function valid, you must call the initialization function of the COM library:
HRESULT COINTIALIZE (IMALLOC * PMalloc);
PMalloc is used to specify a memory distributor, which can specify a memory allocation principle. In general, we set the parameters directly to NULL, then the COM library will use the default memory distributor.
Return value: S_OK indicates the initialization success
S_false indicates that the initialization is successful, but this call is not the first call initialization function in this process.
S_unexpected indicates an error in the initialization process, the application cannot use the COM library
Typically, a process is only initialized to the COM library, and it is meaningless to perform multiple initialization for the COM library in the same module unit. The only function that doesn't need to initialize the COM library is a function that gets the COM library version:
DWORD COBUILDVERSION ();
Return value: high 16-bit main version number
Low 16-bit version number
After the COM program is used after the COM library service, it is usually necessary to call to terminate the COM library service function before the program exit, so that the resources maintained by the COM library:
Void Couninitialize (VOID);
Note: Any process or program module that calls the Coinitialize function or the program module must have a corresponding CounInitialize function call to ensure that the COM library has effectively utilized resources.
(? If you call Coinitialize in a module to return to S_OK, then after you call the Counitialize function, other modules that are also using the COM library will errors? Or COM library automatically checks what modules are in use?)
-------------------------------------------------- -----------------------------
COM library memory management
-------------------------------------------------- -----------------------------
Since the COM component program and the client are established through the binary-level standard, the operation of memory interaction between the COM library and components in COM applications must be used in the COM application. Consistent memory manager. The memory management standard provided by COM is actually an IMALLOC interface:
// IID_IMALLOC: {00000002-0000-0000-C000-000000000046}
Class Imalloc: Public IUNKNOWN
{
Void * alloc (ulong cb) = 0;
Void * Realloc (Void * PV, Ulong CB) = 0; Void Free (void * pv) = 0;
Ulong getsize (void * pv) = 0; // Return the assigned memory size
INT DIDALLOC (VOID * PV) = 0; / / Determine if the memory pointer is assigned by the memory manager
Void Heapminimize () = 0; // Make the stack memory as much as possible, put the memory that is not used
// Operating system for performance optimization
}
Get the Imalloc interface pointer:
HRESULT COGETMALLOC (DWORD DWMEMCONTEXT, IMALLOC ** PPMALLOC);
The first parameter dwmemContext of the CogetherMalloc function is used to specify the type of memory manager. The COM library contains two memory managers, one is the memory manager specified in initialization or its internal default manager, also known as the job manager, which is valid in this process. To get the manager, specify as MemctX_task in the DWMemContext parameter; another is a shared distributor across the process, provided by the OLE system, to get this manager, specified in the dWMemContext parameter to MemctX_shared, use the shared manager Conveniently, you can allocate memory within a process and pass it to the second process, and use this memory even release this memory within the second process.
As long as the return value of the function is S_OK, PPMalloc points to the COM library's memory manager interface pointer, you can use it to operate, after use, you should call the Release member function to release control.
The COM library has three API functions that can be used for memory allocation and release:
Void * CotaskMemalloc (Ulong CB);
Void CotaskFree (Void * PV);
Void CotaskMemRealloc (Void * PV, Ulong CB);
These three function assignments correspond to IMALLOC: Alloc, Realloc, and FREE.
Example: How does the COM program find the corresponding progid value from the CLSID value:
Wchar * pwprogid;
Char pszprogid [128];
HRESULT = :: ProgidFromClsid (CLSID_Dictionary, & PWProgID);
IF (HRESULT! = S_OK) {
...
}
WCSTombs (PSZProgid, PWProgID, 128);
CotaskMemFree (PWProgID); // Note: Must release memory
After calling the COM function progidFromClsid, since the COM library assigns memory space for the output variable PWProgID, the application must call the CotaskMemFree function to release memory after using the PWProgID variable. This example illustrates a case where the memory is allocated in the COM library, and the memory is released in the calling program. Some other functions in the COM library have similar features, especially some functions that contain unordered length output parameters.
-------------------------------------------------- -----------------------------
Component program loading and uninstall
-------------------------------------------------- ------------------------------ The loading of the components in the process:
Customer Call CocreateInstance or COGETClassObject function creates a COM object, in the CogetherClassObject function, the COM library finds the full path to the component program (DLL file) corresponding to the class identifier CLSID according to the information in the system registry, then call LoadLibrary ( In fact, the COLOADLIBRARY function and calls the DllgetClassObject extraction function of the component program. The DllgetClassObject function creates the corresponding class factory object and returns the IclassFactory interface of the class factory object. The task of this CogetherClassObject function is completed, and then the client or COCREATEINSTANCE function continues to call the CREATEINSTANCE member function of the class factory object, which is responsible for the creation of COM objects.
CoCreateInstance
| -Cogetclassobject
| -Get CLSID -> DLLFILE PATH
| -ColoadLibrary
| -Dllfile.dllgetClassObject
| -Return IclassFactory
| -IClassFactory.createInstnace
Loading of processes:
In the COGETCLASSOBJECT function of the COM library, when it finds that the component program is an EXE file (specified by the localserver or localserver32 value in the registry component object information), the COM library creates a process startup component program and brings "/ Embedding" command. Rows of parameters, then wait for component programs; and component programs are started after they check, when they check the "/ Embedding" command line parameters, the class factory object will be created, and then the CoregisterClassObject function registers the class object object to COM. After the COM library checks to the class factory of the component object, the COGETCLASSObject function returns the class object object. Since the class is running in different processes, the client program is a proxy object of the class factory. Once the client or COM library gets the class factory object, it can complete the creation of component objects.
Different creation processes of objects and processes outside the process also affect the implementation process of the CogetClassObject function, which is completely transparent to the client program.
CogetherClassObject
| -Localserver / localserver32
| -EXECUTE EXE / EMBEDDING
| -Create Class Factory
| -CoregisterClassObject (Class Factory)
| -Return Class Factory (Proxy)
Uninstalling of components within the process:
Only when the component program satisfies two conditions, it can be uninstalled, the two conditions are: the number of objects in the component is 0, and the lock count of the class is zero. When these two conditions are met, the DllcanunloadNow lead function returns True. COM provides a function COFREEUSEDLIBRARIES that detects all component programs in the current process. When you discover a DllcanunloadNow function of a component, call the Freelibrary function (actually a COFREELIBRARY function), from the program from the program Unload.
Who calls the COFREEUSEDLIBRARIES function? Because it is impossible to remove yours from memory during execution of the component program, this task should be done by the customer. The COFREEUSEDLIBRARIES function can call the COFREEUNUSEDLIBRARIES function to complete the unloading, but the usual approach is to call the COFREEUSEDLIBRARIES function during the idle processing of the program, which can avoid the call to the COFREEUSEDLIBRARIES function in the program, but no longer The components used are cleared in time, improve the utilization of resources, and the COM specification also recommends this approach. Uninstalling of processes:
The uninstallation of the processes is relatively simple, because the component program runs in a separate process, once its exiting condition is met, it can only be returned from the master function of the process. In the Windows system, the master function of the process is WinMain.
I have said that when the component program starts running, it calls the CoregisterClassObject function, registering the class object to COM, after registration, the reference count of the class factory object is always greater than 0, so the reference count of single-by-class factory object cannot be controlled The process of the process, which is also the cause of the lock and lock operation of the introduction of the class factory. There is similar to the determination of the process outgoing components and the judgments in DllcanunloadNow, but also need to judge whether the COM object exists, and the determination is 0, only when the condition is satisfied, the main function of the process can exit.
In principle, the uninstallation of the procedure assembly program is so simple, but in fact, the situation may be complex, because some component programs can create their own objects during the run, or the program containing the user interface is manually Closing the process, then the process is complex to these actions. For example, the component program is in the running process, and the user opens a file and operates, even if the original created object is released, and the lock counter is also 0, the process cannot be exited, it must continue to serve the user, just like It is the same as the process of user open. For this program, you can add a "user control" tag flag. If FLAG is false, you can directly exit the program directly; if Flag is true, it indicates that the user is involved in the control, the component process cannot be exited immediately. However, the CoreVokeclassObject function should be called to call with the CoregisterClassObject call, leave the process to the user to continue.
If the component program is in the run, the user wants to shut down the process, and this time does not meet the process exit condition, then the process can take two ways: the first method, hide the application, set the FLAG tag to false, then The component program continues to run until the uninstall condition is satisfied; another method is to call the CODISCONNECTOBJECT function, forced the relationship between the object and the customer, and forcibly terminate the process, this method is rude, not advocated, but it is not allowed Use to ensure that the system completes some high priority operations.
-------------------------------------------------- -----------------------------
COM library usage function
-------------------------------------------------- -----------------------------
Initialization Function CobuildVersion gets the version number of the COM library Coinitialize COM library initialization
Couninitialize COM library function service termination
COFREEUSEDLIBRARIES Releases All no longer used components in the process
GUID related function ISEQUALGUID determines whether two GUIDs are equal
ISEQUALID determines whether the two IIDs are equal
ISEQUALCLSID determines whether the two CLSIDs are equal (* Why do you want 3 functions)
CLSIDFROMPROGID string component ID Convert to CLSID form
StringFromClsid CLSID form identification transformation into string form
IIDFROMSTRING string is converted to IID form
StringFromiID IID Convert to Strings
StringFromGUID2 GUID Convert to strings (* why 2)
Object Creation Function CogetherClassObject Get Class Factory Object
CoCreateInstance Create a COM object
COCREATEINSTANCEEX Creates a COM object, specifying multiple interfaces or remote objects
CoregisterClassObject register an object so that other applications can connect to it
CorevokeClassObject cancels the registration of the object
CODISCONNECTOBJECT disconnects other applications and objects
Memory Management Function CotaskMallOc Memory Assignment Function
CotaskMemRealloc memory reassignment function
CotaskMemFree memory release function
Cogether Malloc gets the COM library memory manager interface
-------------------------------------------------- -----------------------------
HRESULT type
-------------------------------------------------- -----------------------------
Most COM functions and the return value type of some interface member functions are HRESULT types. The return value of the HRESULT type reflects some of the functions, and its type definition specification is as follows:
31 30 29 28 16 15 0
| ----- | - | ----------------------------- --------------------
Category Code (30-31) Reflects the result of the function call:
00 call success
01 contains some information
10 warning
11 error
Custom Tag (29) The result is whether the result is a custom identifier, and 1 is, 0 is not;
Operation code (16-28) Identification results Source, on the Windows platform, is defined as follows:
#define facility_windows 8
#define facility_storage 3
#define facility_rpc 1
#define facility_sspi 9
#define facility_win32 7
#define facility_control 10
#define facility_null 0
#define facility_internet 12 # define facility_itf 4
#define facility_dispatch 2
#define facility_cert 11
Operation result code (0-15) reflects the status of the operation, WINERROR.H defines the win32 function that may return the result.
The following is some return values and macro definitions that are often used:
The S_OK function performs success, its value is 0 (note, its value is opposite to TRUE)
The S_FALSE function is successful, its value is 1
The S_FAIL function failed, the cause of failure is uncertain
The E_OUTOFMEMORY function failed, the cause of the failure was unsuccessful for memory allocation
The E_NOTIMPL function failed, and the member function is not implemented.
The E_NotInterface function failed, and the component did not implement the specified interface.
The return value cannot be simply compared to S_OK and S_FALSE, and it is necessary to judge with the SecceEDED and the FAILED macro.
============================================================================================================================================================================================================= ==============================
⊙ Chapter 4 COM Features
============================================================================================================================================================================================================= ==============================
Reusability: inclusive and aggregation
-------------------------------------------------- -----------------------------
Inclusion model:
Component objects perform an interface function (client / server model) of another component object that you created in the implementation code of the interface. This object also implements the code for two (or more) interfaces.
Polymerization model:
The component object passes the interface to the interface query function of the other object that has been created without implementing the code of the interface in the query code of the interface. Another object must achieve a polymerization model (that is, it knows that he is aggregating by another component object) so that the QueryInterface function can work properly.
In the case where the component object is aggregated, when the customer requests the interface that does not support or requests the IUNKNOWN interface, it must give the control to the external object, determine the request result of the client program. The aggregation model reflects the true reuse of the component software.
The key to the achievement of aggregate models in the CocreateInstance function and the iClassFactory interface:
HRESULT COCREATEINSTANCE (Const CLSID & CLSID, IUNKNOWN * PUNKNOWNOUTER,
DWORD DWCLSCONTEXT, Const IID & IID, (void **) PPV);
// Class IclassFactory: Public IUNKNOWN
Virtual HRESULT _STDCALL CREATEINSTANCE (IUNKNOWN * Punknownouter,
Const IID & IID, VOID ** PPV) = 0;
The PunkNownouter parameter is used to specify whether the component object is aggregated. If the PunkNownouter parameter is null, the component object is used normally, otherwise the aggregation is used, and the PunkNownouter is the interface pointer of the external component object.
The reference count member function of the aggregated object under the aggregation model is also specially processed. In the absence of polymerization, a general reference count method can be used. When being aggregated, when the ADDREF / RELEASE function is called by the customer, it is necessary to turn to the AddRef / Release method of the external component object. At this time, the external component object to control the aggregated object must use other reference count interfaces.
-------------------------------------------------- -----------------------------
Process transparency (waiting for learning)
Safety (waiting for learning)
Multi-threaded feature (waiting for learning)
-------------------------------------------------- -----------------------------
============================================================================================================================================================================================================= ==============================
⊙ Chapter 5 Develops COM Apps with Visual C
============================================================================================================================================================================================================= ===================================================================================================================================================================================================================================================================
-------------------------------------------------- -----------------------------
Definition of IID and interface member functions of unknwn.h standard interface IUNKNOWN and ICLASSFACATORY
Wtypes.h includes a description of the data structure used by COM
Objidl.h definition of all standard interfaces can be used for C-language style definitions, or for C languages
COMDEF.H All standard interfaces and CLSIDs for COM and OLE internal objects
Objbase.h Description of all COM API functions
Ole2.h All packaged OLE assist functions
-------------------------------------------------- -----------------------------
Some macros related to the COM interface
-------------------------------------------------- -----------------------------
Declare_Interface (iFace)
Declare interface ifce, it does not derive from other interfaces
Declare_Interface_ (iface, baseiface)
Declare interface ifce, it is derived from Interface Baseiface
STDMETHOD (METHOD)
Declare Interface Member Function Method, Function Return Type HRESULT
STDMETHOD_ (TYPE, METHOD)
Declaration Interface Member Function Method, Function Return Type Type
============================================================================================================================================================================================================= ==============================
⊙ End