COM technology insider summary

xiaoxiao2021-03-06  109

InProcsever32 process COM server localsever32 process outside COM server

InProcSever: delphi creation of the server process com: CreateComObject (const ClassID: TGUID): IUnknown ClassID which is CLSID interface class, inside this function calls the CoCreateInstance, CoCreateInstance encapsulates CoGetClassObject.CoCreateInstance: Creates a single uninitialized object of the class associated with a specified CLSID.Call CoCreateInstance when you want to create only one object on the local system. to create a single object on a remote system, call CoCreateInstanceEx. to create multiple objects based on a single CLSID, refer to the CoGetClassObject function .

It is convenient to use CoCreateInstance when you need to create only a single instance ofan object on the local machine. If you are creating an instance on remote machine, call CoCreateInstanceEx. When you are creating multiple instances, it is more efficient to obtain a pointer To the Class Object's iClassFactory Interface and Use ITHODS As Needed. in The Latter Case, You Should Use The CogetherClassObject function.

COCREATEINSTANCE calls COGETCLASSOBJECT, search the registration symbol, get the DLL position in which the COM class is located and loaded, by calling the DllgetClassObject to the interface class by calling the DLLGETCLASSOBJECT interface class, by calling the method of this class CreateInstance finally needs Interface pointer. As in English Note: When you want to create multiple instances of a COM class, you should call the CogetherClassObject to get the class pointer, and then call the class factory CreateInstance to create an interface. CreateComobject -> COCREATEINSTANCE -> CogetherClassObject ---> DLLGETCLASSOBJECT ----> CREATEINSTANCE

LocalSever32delphi creation process COM server process: CreateComObject (const ClassID: TGUID): IUnknown its ClassID is CLSID interface class, CreateComObject -> CoCreateInstance ---> CoGetClassObject ---> CreateProcess -> CoRegisterClassObject ---> CreateInstance

Aggregation: In general, reusing a Delphi object or C object can be used by inheritance or combination, then the COM object (implemented the COM class of the interface), is a combination of ordinary objects by aggregation, However, it is, the polymerization class must be packaged by the interface method of the aggregated class. When the customer calls the method of the packaging of the aggregate class, the polymerization class calls the customer to the corresponding method of the aggregated class. DCOM: CreateremoteComobject -> COCREATEINSTANCEEX -> COGETCLASSOBJECT - CREATEINSTANCE

Automation: Essentially a COM object that implements the IDispatch interface. An example of an automation, such as editing an Excel form in Word, editing a picture, etc. It is a technology for applying or DLL OLAC programmable control objects to other applications. Providing this object's application is called an automation server, and the application of this object is called an automation controller. The biggest advantage of automation is language-independent. An automation controller controls the automation server developed by any language.

Type tbuttonedit = class (twincontrol) private {private declarations}} public {public declarations}}}

COM separates the implementation and declaration of the class. The interface is a declaration, and CoClass is its implementation, which is included in DLL (in-process), exe (out-process). COM objects behave as an instance of CoClass in memory. The COM server is a binary (DLL or EXE) containing one or more COCLASS .registration is where the registry entry is created, telling Windows, where the COM server is located. Coclass's Guid called CLSID, the interface of Interface is called IID.hresult is COM to return an error and successful integer number. There is no other meaning that does not represent the handle to use the CoCreateInstance, the API function creates a COM object. This API creates an instance through COM object class. The class is a special COM object that supports the iClassFactory interface. The iClassFactory interface implements two methods: CREATEINSTANCE, LOCKSERVER. CREATEINSTANCE Creating a COM object associated with a class factory is to lock the COM server in memory, even if there is no customer to apply it.

MFC and ATL can develop ActiveX control ActiveX controls based on COM technology, and its basic principles are object interfaces and implementation. The client of the ActiveX control is driven through the interface. An ActiveX control is implemented: introducing a COM interface; OLE embedded protocol connection point and property page These several major ActiveX technology COM objects

From a low level, ActiveX control is a COM class that implements some types of interfaces. When the customer can query these interfaces, you can use it.

The three types of interfaces of the ActiveX control: 1. Embedded objects that it implements most OLE documents, In-Place activation, and embedded protocols. IoleObject, IPersistStorage, IdataObject, IoleinplaceActiveObject, IoleinplaceObject, iViewObject2, IrunnableObject 2. Support Properties Page Customer You can modify attributes 3. COM connection technology customers can discover out interface

MFC's support MFC for COM implements a support CCMDTARGET class for COM by adding some virtual functions to the CCMDTARGET class: Implement the IUNKNOWN interface, member variable m_dwref, used to reference counts for six functions for IUnkonwn: InternalAddRef, InternalRelease, InternalQueryInterface, ExternalAddRef, ExternalRelease, ExternalQueryInterface. InternalAddRef, InternalRelease, InternalQueryInterface complete reference counting and Interface query ExternalAddRef, ExternalRelease, ExternalQueryInterface polymerization control agent MFC objects nested composite policy implementation the COM, in MFC, I want to achieve The class of the COM interface is derived from the ccmdtarget. These inheritances implemented interfaces to their own nested classes, MFC use macro begin_interface_part and end_interface_part to generate nested classes

The MFC QueryInterface is a table driver, and its interface mapping is basically the same: message mapping associates a Windows message and a function in the C class, interface mapping puts an interface's GUID and a specific VPTR representative of the interface. . Each CCMDTARGET-based class implementation COM interface With more macros: declare_interface_map, begin_interface_map, interface_part, and end_terface_map to add an interface map (similar to several macros similar to message mapping)

The COM component consists of executable code published in the form of a Win32 Dynamic Link Library (DLLS) or executable file (exe). COM components: Unrelated to language publishing free upgrades can be redistributed on the network in binary form

The purpose of developing COM is to make applications easier to customize, more flexible. Define #define interface struct #define stdmethodCallType_Stdcall in Win32SDK, defined in WINDEF.H. #Define pascal _stdcall_stdcall is Microsoft's extension of the compiler by this tag identifier will be returned to the caller Parameter Removes from the stack _CDECL is a regular C / C call convention, by the caller cleaning parameters

The component is the collection of interfaces. The interface is the invariance of the set interface of the function. Once the interface is published, it will never change all COM interfaces to support an IUnknown interface, define it in unknwn.h header file. This interface contains three functions. So any of the interfaces of the component can be used by the customer to get other interfaces it support, so any interface pointer can be used as an IUNKNOWN interface pointer, and the client gets the iUnknown interface pointer through IUNKNOWN * CREATEINSTANCE (), and then passed Call the queryinterface function to ask if the component supports a particular interface, if support, queryinterface returns a pointer to the interface, otherwise returns an error code HRESULT _STDCALL QueryInterface (const Iid & Iid, void ** ppv); because the interface is essentially a function pointer So the save interface needs to point to the pointer Queryinterace in the pointer QueryNown interface, whether the Queryinteface that is called from which interface pointer is called, the IUNKNOWN interface pointer is the same, that is, the same address. Therefore, when it is judged whether or not the interface is pointing to the same component, it is possible to return the IUNKNOWN interface pointer from these two interfaces to queryInterface. One IID is an interface stdapi dllregisterServer (); stdapi dllunregisterServer (); stdapi in Objbase.h Defined as #define stdapi extern_c HRESULT stdapicallType is expanded after extern "c" hResult _stdcall

Component category: A component category actual mosa is an interface collection, which is assigned a guid, called Catid, for a set of components, if it implements all of the interfaces, you can register it into this A member of the component category. Customers can use the components that are only a component that belongs to a specific setup category through the registry. Uses: Specify an interface collection that must be implemented. Uses: Specify See the set set of interfaces that need their customers (because certain setup needs customers to provide some services to run normally)

Component Category Manager provides management of the establishment category that can be done in a component category, or remove it from it.

COM library: All COM components and customers need to complete some of the same operations, in order to ensure that these exercises are done according to standard and compatible methods, COM defines a library to implement all of these exercises to do this function library in OLE32 Realization in .dll, in the use of functions in the COM library (except COBUIldVersion), the process must call Coinitialize first to initialize the COM library function, you must call Couninitialize. Protest: HRESULT COINITIAALIZE (Void * Reserver) / / Parameter is set to null void coundialzie ();

Memory Management Q: How do I release when the memory allocated in the component is returned to the customer as a parameter: A: Use the task memory distributor provided by COM, call it through the IMALLOC interface. This interface is returned by Cogether Malloc. Allocating memory can be used with iMalloc :: Alloc, and release can be done by IMALLOC :: Free. To simplify, the COM library provides void * cotaskmemalloc (Ulongl CB) // parameter to assign the size of the memory void cotasememfree (void * pv)

PROGID is an easy memory name definition of the design component programmer, which is to get CLSID to use CLSIDFROGID and PROGIDFROMCLSID.

The CLSID in the registry is indicated in the character. In order to convert it to the GUID, you can use StringFromGuid2, you need a Unicode string. In a non-Unicode system, it is necessary to convert its result into a single-byte string, to use the WCSTOMBS function, for example, : wchar_t szCLSID [39]; int r = StringFromGUID2 () CLSID_Component, szCLSID, 39) #ifndef _UNICODE char szCLSID_single [39]; wcstombs (szCLSID_single, szCLSID, 39 (; #endif; other functions: StringFromCSLID StringFromIID StringFromGUID2 above function uses Follow the CotaskMemFree CLSIDFromString IIDFromString interface definition macro: In order to help programmers conversion from c to c , some macros define some macro to customize the C and C programmers. In Objbase.h and BaseTypes.h includes those definitions, for example, interface IX: IUnknown {virtual vodi _stdcall Fx () = 0;} using macros defined below DECLARE_INTERFACE (IX, IUnknown) {STDMETHOD (QueryInterface) (THIS_REFIID, PPVOID) PURE; STDMETHOD (ULONG, AddRef) ( THIS) PURE; STDMETHOD (ULONG, RELEASE) Pure; stdmethod (void, fx) pure;}

Class CocreateInstance Creating the most common ways of components. But the lack of flexibility HRESULT _stdcall CoCreateInstance (const CLSID & clsid, // input IUnknown * pIUnknown, // input DWORD dwClsContext, // input const IID & iid, // input vodi ** ppv // output); a parameter: Component CLSID Parameter 2: Used for Polymeric Component Parameters: Component Performing Sink Parameters 4: Interface IID Parameters 5: Accepting Interface Pointer Parameters Three Triendal Values ​​CLSCTX_INPROC_SERVER CLSCTX_INPROC_HANDLER CLSCTX_LOCAL_SERVER CLSCTX_REMOTE_SERVER Definition in Objbase.H Defined in ObjBase.H constant CLSCTX_INPROC: CLSCTX_INPROC_SERVER CLSCTX_INPROC_HANDLER CLSCTX_ALL CLSCTX_INPROC_SERVER CLSCTX_INPROC_HANDLER CLSCTX_LOCAL_SERVER CLSCTX_REMOTE_SERVER CLSCTX_SERVER CLSCTX_INPROC_SERVER CLSCTX_LOCAL_SERVER CLSCTX_REMOTE_SERVER Note: CLSCTX_REMOTE_SERVER only _WIN # @ _ WINNT> = 0x0400 will be added in the process of creating CLSCTX_ALL and CLSCTX_SERVER in CoCreateInstance not control assembly. If you want to create multiple instances, it is more powerless.

Class Factory: Items that are specifically used to create components. Function to create class factory is: HRESULT _stdcall CoGetClassObject (const CLSID & clsid, DWORD dwClsContect, COSERVERINFO * pServerInfo, const IID & iid, void ** ppv); various parameters CoCreateInstanc substantially the same, but this function returns the interface pointer for the component class factory of. Point to an IclassFactory interface. interface IClassFactory: IUnknown {HRESULT _stdcall CreateInstance (IUnknown * pUnknownOuter, const IID & iid, void ** ppv); HRESULT _stdcall LockServer (BOOL bLock);} can see the member function does not accept the CLSID parameter, that is, it can only be created with The corresponding component passed to the CLSID of CogetClassObject.

IclssFactory: This interface adds permission function on the basis of iClassFactory.

Most of the cases should use CocreateInstanc. In the following two cases, COGETCLASSOBJECT: 1. Use iClassFactory2 to create component 2. You need to create multiple instances of the same component, and you can get higher efficiency using CogetherClassObject. Because you only need to create a class factory.

The class will be implemented by the component developers. Most cases, class mills and components are in the same DLL. COGETCLASSOBJECT completes the creation of the class factory by calling a function dllgetclassObject in the DLL of the Publishing Component. Stdapi DllgetClassObject (Const CLSID & CLSID, Const IID & IID, VOID ** PPV) DllgetClassObject can accept the CLSID of the component such that a DLL can support any number of components. Inclusion and aggregation: COM achieves inheritance. It is a technology that reuses another component. Tolerant: The external component contains a pointer to the internal component interface, and the external component is a real customer of the internal component (any interface of the external component you can request the internal components). External components can re-implement this interface or forward the customer's call to the internal interface aggregation: the external component passes the pointer of the contained aggregate object to the customer, at which point the external component does not need to re-implement the function of the aggregate object, but the external components cannot be Retrofit any function of the polymer object. For customers (using external components), it should not be known to interact with two different components, otherwise it is to destroy the encapsulation. It is possible to achieve aggregation because of the results of queryinterface. The goal of aggregation is that when the customer calls the interface function of the aggregate object, the customer is confident that it is dealing with the external interface, that is, the customer can use, and what should be seen. Internal components should be transparent to the customer. That is When the customer gets the interface pointer of the internal component, the component function view he sees should be constant.

(Example 1: It calls QueryInterface when this pointer is called QueryInterface when you call QueryInterface when you use an external component. You should be the same interface. At this time, the IUNKNOWN interface of the internal component is then queried to the external component. Query) (Example 2: Component A Implementing Interface IX, aggregating component B IY interface, for customers, IX and IY should be seen as an interface implemented, the call to these two interfaces is not Difference. If the component B implements the IY and IZ interfaces, the customer should not query the IZ interface. Of course, the component B is not a aggregate object, of course, the interface IZ should be found. At this time, you should find IY, but You should not find IZ. You should find IX through IY IY->, or you should not find IZ.) The root source of the above problem is that the customer can get two different iUnknown interface, so at this time, IUNKNOW of the aggregation component needs to pass. Special treatment. At this time, the interface of the internal components must use an external component implemented IUNKNOWN interface, and the IUNKNOWN interface of the external component is referred to as an external IUNKNOWN interface or a control IUNKNOWN interface. The simplest way to resolve the inner component IUNKNOWN to the external IUNKNOWN interface query, the aggregate object requires a pointer to the external iUnknown interface, and knows that he is aggregated (because when there is no aggregation, fundamental No need to forward call) HRESULT _STDCALL COCREATEINSTANCE (Const CLSID & CLSID, IUNKNOWN * PUNKNOWNOUTER, / / ​​This pointer refers to the IUNKNOWN Const IID & IID, Void ** PPV of the external component; when the PunkNownouter pointer is non-empty, indicating that the component is a polymeric object. The aggregate object actually implements two IUNKNOWN interfaces, and the normally IUNKNOW is called a non-proxy IUNKNOWN interface, and the aggregation is called a proxy IUNKNOWN interface. 1. Customer-> Polymeric Object Interface -> Proxy IUNKNOWN -> External IUNKNOWN 2. External Components -> Proxy IUNKNOWN -> Internal Components (External Components Controlling the Life Dynamics of Internal Components by Non - Agent IUNKNOWN), ADDREF () of non-proxy iUnknown interface is actually the same as the implementation of the iUnknown's basically IUNKNOWN interface. The agent IUNKNOWN interface implements two tasks, one is forwarded to the external (IUNKNOWN) when aggregation, and is forwarded to the internal (non-agent iUnknown) when the call is not aggregated. Because this external component must request a non-proxy IUNKNOWN interface when creating an external component, save it. Otherwise, this interface will not be obtained in the future.

When the customer creates an external component, the external component of the external component will create internal components and request the aggregated interface. When the request is successful, the addRef () of the external component will call the external component, the following example CB aggregates the IY interface of the CA // CB :: m_pinnerunknown -> CA :: IY // CA :: m_pouterunknown -> cb // This function creates CA, and requests CA's iUnknown interface 1 PB-> Initialzie Poutunknown) // poutunknown -> CB

CoCreateInstance (CLSID_CA, pOutUnknown, CLSCTX_INPROC_SERVER, IID_IUNKNOWN, & m_pInnerUnknown); // CA requested class in the process plant pFactoryA the CB transmission to the IUnknown CA 2 pFactoryA-> inside CreateInstance (pOutUnknown) // count is incremented reference herein When CB destructure reduces 3 PA-> NOPROYQUERYINTERFACE (IID_UNKNOWN, (Void **) & cb :: m_pinnerunknown) // actually call CA :: NoproxyQueryInterface, CA forwards the reference count to the outside, adds CB reference count 4 CB: : m_pinnerunknown-> queryinterface (IID_IY, (Void **) CB :: m_piy); 5 poutunknown-> release () // corresponds to 7, should not maintain a reference count 6 PB-> queryinterface (IID, PPV) for M_PIY / / The interface CB :: ~ cb () {m_cref = 1; iUnknown * poutunknown = this; poutunkn-> addref () // Restore 4 reference count, corresponding 5 m_piy-> release () // correspondence 4 if (m_pinnerunknown! = Null) {m_pinnerunknoven-> release;}} // The above visible CB is destructed, m_cref = 1, so the reference count is equal to how much does not make sense, its existence is just when equal to 0 , Release the assembly. // When the customer uses the interface of the CB component, call Release, at this time, the reference count has been equal to 0, the component is called by the delete, the destructor, if the m_cref is not set to 1 // When the temples M_PIY, the reference count is made Changes to 0, the destructor is again called to form a cycle. // 4 After the IY interface is requested, since it is not necessary to maintain a reference count, but cannot use m_piy-> release (), because this may release some of this interface to occupy some resources //, so you should use it to pass CocreateInstance's pointer PoutunkNown to call Release ();

Blind aggregation When an external component does not have a client request, it does not check the aggregate interface, but

Else {PinnerunkNown-> QueryInterface (IID, PPV);} This aggregation may appear interface is not compatible, there are two ways to solve problems 1. Interfaces that are often incompatible with metareads are often overlap with interfaces of aggregated objects and external components. The interface called element interface that cannot be conflicted. 2. Matching the knowledge provided to internal components or customers about external components.

In order to better use a polymeric object, it is necessary to provide the status information of the internal components to the customer or external component, and can add an interface to the internal components to the internal components.

Custom components: COM components can achieve virtual callback client components call IX --------------> ix custom icustomize <--------- Component calls icustomize, The opportunity to provide customers with good interfaces generally provide a default customer call IX for custom interfaces ------> O --- ix icustomize - o <--------- - Component calls iCustomize aggregation or tolerate CCUSTomize Components CCUSTOMize ICUSEMize's default implementation programming job simplified client: Smart pointer server: Package process external server passes the address space of the process to another process, must be adjusted. Adjusting the processes of the process, you can implement an interface called IMARSHAL. Agent: EXE server, the customer agrees that the DLL of the imitation component is communicating, this DLL can complete parameter adjustment and LPC calls. Remedy agency residual root: It is also a DLL that adjusts the data from the customer, adjusts the customer back to the customer -----> Agent DLL - Adjustment -> LPC ---> Residual root DLL - anti-adjustment -> Components

Scheduling interface and automation

转载请注明原文地址:https://www.9cbs.com/read-124894.html

New Post(0)