"COM technology insider"
Chapter 1 Components
1, COM, that is, component object models, is about how to establish components and how to construct applications through components. 2, the advantage of the component: the application can develop changes over time; custom applications; component libraries; distributed components. 3. The need for components: Components must be dynamically connected; must hide their internal implementation details. 4, COM component is the executable code consisting of Win32 Dynamic Link Library (DLLS) or Executable File (Ex with)
of. Compliance with COM specification will be able to meet all the needs of the component family. COM components are dynamic links, COM
Use the DLL to dynamically link the components. It is easy for packaging of COM components. COM components declare in a standard way
Buy their existence. The COM component is an excellent method for providing object-oriented API or services to other applications. 5, COM is not a computer language. 6. It is not appropriate to compare COM with DLL. In fact, COM uses DLL to provide dynamic links to components. 7, COM is not a function set like Win32API, which is more important to write in the form of object-oriented API
Method of components of the task. 8, COM is not similar to the C class library such as MFC. CoM provides developers a component library that developed and languages
The method, but COM itself does not provide any implementation. 9, COM has an API called a COM library, which provides components management services that are very useful for all customers and components.
.
Chapter 2 Interface
1. The interface between CoM is everything. (1) The interface can protect the influence of the system free of the external change. (2) The interface allows customers to handle different components in the same way. 2, (1) The COM interface is implemented with pure abstract base classes in C . (2) A COM component can provide multiple interfaces. (3) A C class can use multiple inheritance to implement a component that can provide multiple interfaces. 3, class is not a component. 4, the interface is not always inherited. The inheritance of the interface is just a detail of implementation. In addition to using a class
In addition to several different interfaces, you can also use a single class to implement each interface and use a pointer to these classes. 5. Components can support any number of interfaces. To support multiple interfaces, multiple inheritance can be used. Support multiple interface components
It can be seen as a collection of interfaces. 6. The invariance, polymorphism, and interface inheritance of the COM interface. (1) Once an interface is published, it will always remain unchanged. When the component is upgraded, there is generally not modified
The interface, but add some new interface. (2) Polymorphism is that different objects can be handled in accordance with one way. 7. Virtual Function Table (VTBL): Contains a set of pointers that point to virtual functions. Defining a pure abstract base class is also a corresponding memory structure. But this memory is just when this abstract base class is implemented in the derived class.
Will be assigned. When the derived class inherits an abstract base class, it will inherit this memory structure. 8. In COM, access to a component can only be done through the function, and must not pass the variables directly.
9. The true power of the interface is that all classes of this interface can be processed by the customer in the same manner.
Chapter 3 QUERYINTERFACE functions
1. Interface query: The interaction of the customer's same components is done through an interface. When the client querying the other interfaces, it is done through the interface.
of. This interface is iUnknown. The definition of the IunkNown interface is included in the unknown.h header file in Win32 SDK. interface IUnknown {virtual HRESULT _stdcall QueryInterface (const IID & iid, void ** ppv) = 0; virtual ULONG _stdcall AddRef () = 0; virtual ULONG _stdcall Release () = 0;} defines a function named QueryInterface of the IUnknown . Customers can call QueryInterface to determine if components support a particular interface. 2, all COM interfaces need to inherit iUnknown. 3. Since all COM interfaces have inherited IUNKNOWN, the first three functions in the VTBL of each interface are
QueryInterface, addRef and release. If the first three functions in the VTBL of an interface are not these three, then it will not
It is a COM interface. Since all interfaces are inherited from iUnknown, all interfaces are supported
QueryInterface. Therefore, any interface of the component can be used by the customer to get other interfaces it support. 4, non-virtual inheritance: Note that IUNKNOWN is not a virtual base class, so the COM interface does not inherit IUNKNOWN in virtual way.
This is because it causes VTBL that is incompatible with COM. If the COM interface inherits iUnknown, then the COM interface VTBL
The three functions of the first three functions are not the three member functions of iUnknown. 5, a quertynterface can be implemented in a simple if-life-else statement, but the CASE statement is unused, because
The interface identifier is a structure instead of one. 6, multiple types and type conversion 7, queryinterface rules (1) QueryInterface returns to always the same IUNKNOWN pointer. (2) If the customer has gone an interface, it will always get this interface. (3) Customers can get the interface already owned again. (4) The customer can return to the starting interface from any interface. (5) If a particular interface can be obtained from an excuse, this interface can be obtained from any interface. 8. The IID of the interface determines its version. When you change any of the following conditions, you should specify a new ID: (1) number of functions in the interface. (2) The function of the interface is the order. (3) Parameters of a function. (4) The order of a function parameter. (5) Type of a function parameter. (6) Function Possible return value. (7) The meaning of function parameters. (8) The meaning of the function in the interface. 9. Avoid violations of implicit and approximately: (1) make the interface to work properly regardless of its member function. (2) Forced customers to use this interface in a certain way and clear this in the documentation.
//
Chapter 4 Reference Count
1. The other two member functions of IUNKNOWN's differential control IUNKNOWN is to provide customers with a way to indicate when
A means of an interface. 2. AddRef and Release implementation is a memory management technology called reference count. The reference count is the easiest way to make the component to delete yourself and the highest efficiency. The COM component will maintain a value of a reference count. This reference count value will increase when the customer gets an interface from the component.
. When the customer uses an interface, the reference count value of the component will be reduced by 1. When the reference count value is 0, the component can bring yourself
Remove in memory. 3. Correctly use the reference count rule: (1) call AddRef before returning. For those functions that return the interface pointer, apply the appropriate pointer to add AddRef before returning. These functions include QueryInterface and CreateInstance. This makes the customer get an interface from this function
Once, it will not need to call AddRef. (2) Call Release after using the interface. The Release function of this interface should be called after using an interface. (3) Call AddRef after assignment. When assuring an interface pointer to another interface pointer, you should call AddRef. change
In order to increase the reference count of the corresponding components after another reference to the interface. 4. In the customer's view, the reference count is on the interface level instead of the component level. 5. Why choose to maintain a reference count independently instead of the entire component maintenance reference count? (1)
Program debugging is more convenient; (2) Support resources on-demand. 6, an example AddRef & Release of ULONG _stdcall AddRef () {return InterlockedIncrement (& m_cRef);} ULONG _stdcall Release () {if (InterlockedDecrement (& m_cRef) {delete this; return 0;} return m_cRef;} 7, when establishing a new component It should be established a reference to this component. So when you create a component, return the pointer to the customer
Previously, the reference count value of the component should be increased. This allows programmers to do not have to call CreateInstance or
After queryinterface, I remember to call AddRef. 8, the reference count rule optimization: (1) Output parameter rules: Any function that returns a new interface pointer in the output parameter or 诶 return value must be connected
Iddref. (2) Enter the parameter rule: The interface pointer to the incoming function, no need to call AddRef and Release, because the function of the function
Nesting is nestled within the caller life cycle. (3) Input - Output Function Rules: For interface pointers passing with input-output parameters, you must give it another one
The interface pointer is called it before it is RELESE. Before the function returns, you must also call the interface pointer saved in the output parameter.
AddRef. Such as: void ExchangeforcachedPtr (INT I, IX ** PPIX) {(* PPIX) -> fx (); // do something in-parameter. (* Ppix) -> Release (); // Release In parameter. * PPIX = g_cache [i]; // get cached pointer. (* ppix) -> addref (); // addref pointer. (* ppix) -> fx (); // do something with out-parameter.} (4 ) Local variable rules: For local copying interface pointers, because they are only existing in the life cycle of functions,
This does not need to call AddRef and Release. (5) Global variable rules: For interface pointers saved in global variables, before passing it to another function,
It is necessary to call its addRef. Since this variable is globally, any function can terminate its life by calling its release.
period. For interface pointers saved in a member variable, it should also be processed in this way. Because any member functions in the class can change the status of the interface pointer. (6) The rules that cannot be determined: AddRef and Release pairs should be called for any case where you cannot determine.
Chapter 5 Dynamic Link
1. Output function from DLL: Tag with Extern "C". 2. When using VC, you can use dumpbin. EXE to get a list of symbols output in a DLL. As of the following command:
DUMPBIN -EXPORTS CMPNT1.DLL3, loaded DLL: LoadLibrary as a parameter with the name of the loaded DLL and returns a handle to the loaded DLL.
Win32's getProcAddress function can use this handle and the name of the function to be used, and then return to a secondary function
Pointer. 4. Use the DLL to implement the components: DLL can share the address space of the application they will entered.
//
Chapter 6 About HRESULT, GUID, Registry and Other Details
1, the structure HRESULT value: _________________________________________________________ | | | | | | 15bits device code | 16bits return code || __ | _________________________ | ______________________________ | 31 30 16 15 0
2. Common HRESULT values: 3, generally can't directly compare the HRESULT value to a success code (such as S_OK) to determine if a function is successful.
It can directly compare it to a failed code (such as E_FAIL) to determine if the function call failed. Should be used
Secceeded and Failed Macro. HRESULT HR = COCREATEINSTANCE (...); if (Failed (HR)) return; hr = pi-> queryinterface (...); if (succeeded (hr)) {PIX-> fx (); PIX-> Release ();} pi-> release ();
4. Currently defined device code: -------------------------------- Facility_Windows 8facility_Storage 3Facility_sspi 9facility_rpc 1facility_win32 7facility_Control 10Facility_null 0facility_itf 4facility_dispatch 2facility_cert 11 ----------------------------------
5. Some general rules on defining their own HRESULT: (1) Do not use values in the 0x0000 and IX01FF range as return code. These values are the facility_itf generation defined for COM
The code is kept. Only by following this rule is not allowed to confuse the code you defined by your own yourself with the code defined by COM. (2) Do not spread the facility_itf error code. (3) Use common COM success and fail code as much as possible. (4) Avoid defining its own HRESULT, and an output parameter can be used in a function. 6. Use the make_hresult macro to define a HRESULT value, which can generate a HRESULT value based on the severity level, device code and return code. Such as: make_hresult (severity_error, facility_itf, 100); 7, GUID is the first letter of English Globally Unique Identifier (globally unique identifier). IID is a 128 ratio
A GUID structure of the special (16) byte. 8. Generate guid: uuidgen.exe and guidgen.exe9, guid comparison: operator ==; Equivalent function iequalguid, iSequaliID, ISEqualClsid. 10. The GUID is used as the component identifier 11, and since a GUID value uses 16 bytes, the GUID parameters are generally not available. And a lot of use is by reference
Hand. 12, COM only uses a branch of the registry: HKEY_CLASSES_ROOT. 13. Registration table CLSID is a string with the following format: {******** - **** - **** - **** - *********** } 14. The default value for the subkey keyword of the CLSID keyword is the DLL file name in the component. 15, some special keywords: (1) appid: The role of sub-key under this key is to hide an APPID into a remote service.
The name of the device. Distributed COM will use this keyword. (2) Meet the category: This branch of the registry can map the CACID (component category ID) into a particular component category. (3) Interface: Used to map IID into information related to an interface. (4) Licenses: Save some license information to authorize the use of COM components. (5) TypeLib: The type library keyword saves information about the parameters used by the interface member function. 16, PROGID naming convention:
. 19. Components category enables developers to determine whether it is required to interface without creating component instances. One
The component category is actually an interface collection, which will be assigned to a GUID, which is called a CACID at this time.
For a component, if it implements all of the interfaces of a component category, then it can register it into this component category.
A member. In this way, customers can accurately find it by selecting components that belong to a particular component category from the registry.
The required components. 20. Use of component categories: Specify an interface collection that must be implemented; used to specify the assembly to provide the interface set by its customers. 22. In addition to other functions in the COM library (except COBUILDVERSION, this function will return the version number of the COM library)
The process must first call Coinitialize to initialize the COM library function. When the process no longer needs to use the COM library function, you must call
Couninitialize. For each process, the COM library function is only initialized once. This is not to say that you can't call multiple times.
Coinitailize, but you need to guarantee that every Coinitialize has a corresponding CounInitialize call. When the process has
After adjusting Coinitialize, the return value obtained again to call this function will be s_false and no longer s_ok.23. OLE is based on COM, which adds to type libraries, clipboard, drag and drop, ActiveX Document, automation
And the support of the ActiveX control. Additional support for these features in the OLE library. Adjusts when these features need to be used
Use Oleinitailize and OleunInInInIget instead of Coinitailize and Couninitialize. OLE * function will call
CO * function. However, if there are no additional functions in the program, use OLE * will cause waste of resources. 24. Standard methods for allocation and release memory in COM: Task Memory Distributor. With this dispenser, components can provide customers with
A piece can be deleted by the customer. It can be used in multi-threaded applications. Some convenient functions: void * cotaskmemalloc (ulong cb // size in bytes of block to be allocate); void cotaskmemfree (void * pv // Pointer to memory block to be freed); 25, StringFromGUID2 can convert an GUID to A string: wchar_t szclsid [39]; int R = :: stringFromGuid2 (clsid_component1, szclsid, 39); Parameters transmitted to StringFromGuid2 are a Unicode string (ie a width character wchar_t type array rather than Char Class
Model array). In a non-Unicode system, it is necessary to convert the results into single-byte characters (char). To this end, you can make