COM based component model
COM based component model
A dynamic link library:
Dynamic linked library is the most-COM Component Object-bearing (do not care about ocx, it is also dll, but changed it to suffix). Of course the same is also Exe (TTS in the TextToSpeech object is an example), but in fact much less.
Windows in the early dynamic linked library state is the emergence of a revolution. It changed the life of Windows, as well as the current Windows operating system hegemony to lay a solid foundation. (Windows on the history issue, I have not made too clear. VCKBASE please the historians to come as soon as possible to write an article ^_^)。
Microsoft's dynamic link library is explained:
Dynamic Link Library (DLL) as a shared library is the executable file. Dynamic Link provides a means for the process can not call a function of its executable code. Function of executable code is located in a DLL, the DLL contains one or more has been compiled, and links with the use of their stored separately from the process of the function. DLL also help to share data and resources. At the same time a number of applications can access memory in a single DLL copy of the contents.
Ah, very clear. First of all dynamic link library is an executable file (Microsoft explained that the exe called directly from the executable file), which contains a group inside the need to share the function. When used, the dynamic link library (and Windows) will provide a way to make our application can call them function. In addition, the dynamic link library will include some resources (such as: icons, dialog template, etc.). In MFC, Microsoft in the existing dynamic link library application on the basis of a number of techniques to provide some additional features, such as the MFC category is derived.
Dynamic Link Library links manner broadly divided into two categories: static and dynamic links.
Static links called implicit link, which links way that we do not have language in the code to instructions system, we have the applications to load the dynamic link library. Static link its statement on engineering properties (or use # pragma comment (lib, "XXX.lib"), and this can be # include together). In the designation only need to enter the dynamic link library into the corresponding file (. Lib). Then you can be anywhere in the procedure call ordinary function the same as calling the DLL function in the (of course, you need to include the corresponding headers. Under normal circumstances, and the first document will be given a document LIB ). This approach generated initialization procedures in the operation of the time (specifically what time is not very clear, but I can be sure in the ^_^), before WinMain function will be automatically loaded dynamic link library in the system environment , and its mapping our application of the process to. When we call a definition of our process does not function, VC operation will be adopted by the LIB files to find the relevant information of the corresponding DLL function and call it. At the end of the process, the system will Xie containing dynamic link library.
Dynamic Link called Explicit links, as the term suggests, we must let this way in the code by calling the API to load the explicit dynamic link library. COM component model are all this way to load module components within the process (is Dll). (I think Microsoft's terminology some confusion Jerusalem). This method has many advantages, it can decide on the specific operation, which links to load libraries, which function to call thisæ‰å«â€¦ dynamic link it.
To use the dynamic link library is not difficult, we must first call LoadLibrary, the prototype is as follows:
HMODULE LoadLibrary (LPCTSTR lpFileName / / file name of module);
Parameters lpFileName is to load the dynamic link library file. If the load is successful, it will return its handle. Otherwise, the return NULL.
And the API is FreeLibrary on the match, the prototype is as follows:
BOOL FreeLibrary (HMODULE hModule / / handle to DLL module);
This I do not have to say much on the bar.
When the dynamic link library was LoadLibrary by loading, the C runtime through _ DllMainCRTStartup to complete DLL initialization, such as the global object (variables), the static member variable, and given initial formation. The most important thing is it will be called DllMain functions. A dynamic link library must have this function, as applications must have the same main or WinMain. It is the prototype:
BOOL WINAPI DllMain (HINSTANCE hinstDLL, / / handle to the DLL module DWORD fdwReason, / / reason for calling function LPVOID lpvReserved / / reserved);
You can DllMain function to complete your DLL initialization of the environment and Analysis of operational configuration. Ah, the matter is this:
DllMain is called Four, which can be from the four parameters were fdwReason out:
They are
1. DLL_PROCESS_ATTACH, when the dynamic link library will be loaded to the process, called DllMain.
2. DLL_THREAD_ATTACH, when the process of the establishment of a new thread, the process will call it already loaded on the dynamic link library DllMain.
3. DLL_THREAD_DETACH, when at the end of a thread, the process has been loaded so called dynamic link library DllMain.
4. DLL_THREAD_DETACH, when the dynamic link library or by Xie contained at the end of the process, called DllMain.
Thus, DllMain response function can be a dynamic link library of the life cycle.
When loading successful, we will get a handle HMODULE. Handle this with the use of application examples HINSTANCE handle very similar (to trace definition, is HINSTANCE HMODULE). We can use some API function to use HMODULE handle:
LoadBitmap, LoadIcon, LoadString,…, GetProcAddress etc. Among them, the most important thing is GetProcAddress. It is used to link the return of the function of a function pointer, and then we can call this function pointer to the function of the link. (If you function pointer citizens who are not good, then the best to look at the C \ C + + grammar books. Function pointer, I think the statement is very strange ways) of its prototype are as follows:
FARPROC GetProcAddress (HMODULE hModule, / / handle to DLL module LPCSTR lpProcName / / function name);
Ah, I do not hModule said. LpProcName parameter is a string, the string words we find a function of the function name. If found, it would return to this function pointer, or else return NULL.
For example:
For example, there is a link library is "int Plus (int nAugend, int nAddend)", I would like to call it.
HMODULE hMathLib = LoadLibrary ( "Math.dll"); int (* MyProc) (int, int) = NULL; int x = 1, y = 1; MyProc = (int (*) (int, int)) GetProcAddress (hMathLib "Plus"); If (MyProc! = NULL) (printf ( "% d", (MyProc *) (x, y));) FreeLibrary (hMathLib);
If I, as well as the link library no problem, I think, should be the output of 2.
I still think that the function pointer very strange statement, readability is not high, so I will be for a general way.
# Define DefMathProc (name) int (* name) (int, int) # define FUNCTION (name) (* name) DefMathProc (MyProc) = NULL; MyProc = (DefMathProc ()) GetProcAddress (hMathLib "Plus"); nResult = FUNCTION (MyProc) (x, y);
Though there may be a warning, but I think that some will be uncomfortable.
Ah, dynamic link library that the basic situation. Specific dynamic link library will be prepared and COM component in the preparation of a follow-up chapters on.
Second, the object-oriented component model - COM
Windows System dominant position within the annotations of 34 will not be shaken. Therefore, it is more than n Windows development platform in front of us. N various development language is flourishing ah. So, we like the Bible said,æ“ç€different languages, can not communicate with each other. In order to change this reality, and the Bill on the lovely stand out, "even to change the world!." Microsoft to develop a common interface specification based on the binary - Component Object Model (COM). However, at the beginning of the COM goal is not to solve the common interface, but for complex documents (OLE) is realized. Because of language has nothing to do now, the process transparent, reusability, confidentiality (unless the master master high master, who can see the coding techniques to achieve), and the preparation is not difficult, as a development application extensive technical.
1) and the Component Object Interface
COM, COM interface is the foundation.
Below, please allow me to use C + + object to an analogy.
COM and C + + object is essentially the same meaning. It is a function of attributes and logical whole. It is a physical object, operating through its interface, you can use the functions it provides.
C + + interface equivalent to the targeted public members. It is exposed to external users, the user should only be allowed to call these storms visible on the surface of the interface to the use of object function. And the public is that members of different interface is not a variable is not a function, it should function as a team. Logically, this should be a function of group-related functions. A component object can have many ports.
I only know that the C + + COM method, as Dephi I know nothing about.
C + + method is: C + + class object to the realization of complete component object from C + + class to represent pure virtual interface. C + + multiple inheritance of objects through multiple interfaces to the owners of multiple interfaces.
Below, I will give an example to illustrate C + + object and interface components of the relationship between (the example below is not a COM achieved, only that component object to the relationship with the interface)
If I do a person's Component Object so, I must first define some interface to the external manifestations that behavior.
Class physiology (public: virtual void eat (Food in) = 0; virtual void drink (Liquid in) = 0; virtual Somethings toilet () = 0;); class psychics (public: virtual Sound laugh () = 0; virtual Sound cry () = 0; virtual Sound angry () = 0;); class dynamics (public: virtual Speed run () = 0; virtual Speed walk () = 0; virtual Interval jump () = 0;);
I will be divided into the actions of the physiology, psychology and kinetics three categories, namely that people behave differently. Well, so three groups of related functions that three interfaces. C + + Component Object is the realization of multiple interfaces from these derivative, and realize them. In this way, we get a Component Object (statement ah, this example is only a concept that, the real COM Component Object also required some NEE).
Class human: public physiology, public psychics, public dynamics (public: void eat (Food in) (cout << "Good! Very delicious!";) Void drink (Liquid in) (cout << "No! I am not drunk ! ";) Something toilet () (cout <<" hum……. "; return dejecta ();) Sound laugh () (return Sound (" Ha… Ha… Ha ");) Sound cry () (return Sound ( "dad! Don't beat my buns.");) Sound angry () (return Sound ( "where did you go last night? Darling.");) Speed run () (cout << "Run, Police come ! "; return 20km / h;) Speed walk () (cout <<" out. yegg, I am no… not afraid o…. of y… you. "; return 1m / s;) Interval jump () (cout << "Yeah…."; return 4m;));
Thus, a component object on the end of the definition. When using the component object, the system gives you a pointer. It is a realization of the component object of the virtual guide, we can use it to call for the Component Object achieved by the pure virtual function category (of course, we have to choose the right virtual guide category as long as support on the Component Object can be.)
In short, a component object is characterized by the external interface is different category these virtual components to users display their components provided by the function.
Note: If your C + + virtual function not of it very, then ask someone to a C + + grammar books to look at. VCKBASE or see section 12 of the "Dynamic Analysis of the series."
2) identifier (GUID)
Above, I said COM component is based on the binary. So we should use signatures (for example, class name, interface) to designate a component is obviously not the ideal (at least in some trouble identification). Well, since the binary system is the most convenient course, is the use of digital identification. Thus, Microsoft definition of such a structure standards:
Typedef struct _GUID (DOWRD Data1; WORD Data2; WORD Data3; WORD Data4 [8];) GUID;
Structure used to store digital information, and knowledge to form a COM object, as well as other COM interface elements. This structure is called identifier.
In C + + is an identifier so that:
Extern "C" = (const GUID CLISID_MYSPELLCHECKER 0×54bf6567, 0×1007, 0×11d1, (0xb0, 0xaa, 0×44, 0×45, 0×53, 0×54, 0×00, 0×00))
The same identifier in other non-C environment is such that:
(54bf6567-1007-11d1-b0aa-444553540000)
This identifier represents a COM object, it is because of a COM object identifier name for all to CLISID_ prefix. While the interface is IID_ for the prefix. Do not ask me, and the object identifier specific definition of what relationship. I do not know. They simply do not have any relations. In the preparation of a COM object, we will use a random method to determine its identifier (this work can be to help us get VC). Once the COM object identifier and get a release out, then it can not be changed. Also, do not worry GUID will be conflict. If you have already passed the high school math, then please settle 128 binary, the probability of how many repeat. If you really found GUID there is a conflict, (you have to guarantee that this is not man-made), I suggest you rush to an area bar to buy lottery tickets. You away from the near 5 million.
3) IUnknown interface
COM mode all must abide by certain norms interface, which is the origin of IUnknown interface. 1 each interface must inherit from this interface. In C + +, Microsoft has a good definition we IUnknown:
Typedef GUID IID; class IUnknown (public: virtual HRESULT _stdcall QueryInterface (const IID & iid, void ** ppv) = 0; virtual ULONG _stdcall AddRef () = 0; virtual ULONG _stdcall Release () = 0;);
Note: void * can point to any object. When I began to void * did not understand the point. Here are the reasons for the use of importedä¼ å‡ºwith pointer types of uncertainty.
QueryInterface function function is when we get an interface guidelines, and we want another interface guide, to help. We want to have our interface identifier iid pass, will be a guide to the transmission & ppv. If QueryInterface successful, it will return to S_OK. We pointer in the direction we want to be the interface.
AddRef, Release mechanism for the realization of the reference count.
In the binary system, the Component Object unlike C + + objects in the environment as a clear survival. This situation may arise, the two (or more) places (probably between different procedures, and might be different between threads) at the same time the use of a component object, if one of the places delete swap the Component Object words. Other places unlikely to know that when they try to call it like this, ranging from lead to serious injuries, while in leading to death. This is not what we wish to see. Therefore, the COM model for a system of reference count mechanism.
When a local start using object, it must call AddRef () first. When we use QueryInterface, QueryInterface must we call a AddRef (). AddRef () component will target the reference count by one. When this place would no longer use the object, it must call Release () first. Release () component will target the reference count by one. When the Component Object reference count becomes 0, that no one go on the use of the component object. At this time, component object should end their own lives. Thus, ensuring the survival of the component object during other security procedures.
Of course, you can use the application of its own mechanisms, as long as you act on the support AddRef and Release. For example, do not set targets of the reference count, but each interface for the creation of a reference count. When all the interface reference count to 0, delete objects.
Well, in the previous example, I do not have to comply with IUknown norms, Below I have to abide by it. I last used the same things the…… omitted.
/ / (6AAF876E-FCED-4ee0-B5D3-63CD6E2242F5) static const GUID IID_IPhysiology = (0×6aaf876e, 0xfced, 0×4ee0, (0xb5, 0xd3, 0×63, 0xcd, 0×6e, 0×22, 0×42, 0xf5)); class IPhysiology: (public IUnknown public:……) / / (183FC7A1-4C27-4c38-B72D-D1326E2E8A7C) static const GUID IID_IPsychics = (0×183fc7a1, 0×4c27, 0×4c38, (0xb7, 0×2d, 0xd1, 0×32, 0×6e, 0×2e, 0×8a, 0×7c)); class IPsychics: public IUnknown (public:……) / / (5F144D5C-A20C-42e7-8F91-4D5CAE430B29) static const GUID IID_IDynamics = (0×5f144d5c, 0xa20c, 0×42e7, (0×8f, 0×91, 0×4d, 0×5c, 0xae, 0×43, 0xb, 0×29)); class IDynamics: public IUnknown (public:……) / / (ABFA7022-7E2F-4d0e-8A4F-F58BBCEBB2DA) static const GUID CLISID_Human = (0xabfa7022, 0×7e2f, 0×4d0e, (0×8a, 0×4f, 0xf5, 0×8b, 0xbc, 0xeb, 0xb2, 0xda)); class human: public IPhysiology, public IPsychics, public IDynamics (public:…… human () (m_ulRef = 0;) HRESULT QueryInterface (const IID & iid, void ** ppv) ( if (iid IID_IUnknown == | | == IID_IPhysiology iid) (* = static_cast <IPhysiology*> ppv (this); (IPhysiology *) (* this)) -> AddRef ();) else if (iid == IID_IPsychics) (* = static_cast <IPsychics*> ppv (this); (IPsychics *) (* this)) -> AddRef ();) else if (iid == IID_IDynamics) (* ppv = static_cast <IDynamics*> (this); (IDynamics *) (* this)) -> AddRef ();) else (* ppv = NULL; return E_NOTINTERFACE;) return S_OK;) ULONG AddRef () (return m_ulRef + +;) ULONG Release () (m_ulRef — ; if (m_ulRef <= 0) (m_ulRef = 0; delete this;) return m_ulRef;) ULONG m_ulRef;);
So that our component object to the definition entirely.
Here is our Component Object IDL description and the description of graphics
# Include "olectl.h" import "oaidl.idl" import "ocidl.idl" [object, uuid (6AAF876E-FCED-4ee0-B5D3-63CD6E2242F5), nonextensible, helpstring ( "IPhysiology interface"), pointer_default ( unique)] interface IPhysiology: IUnknown (void eat (Food in); void drink (Liquid in); Somethings toilet ();); [object, uuid (5F144D5C-A20C-42e7-8F91-4D5CAE430B29), nonextensible, helpstring ( " IPsychics interface "), pointer_default (unique)] interface IPsychics: IUnknown (Sound laugh (); Sound cry (); Sound angry ();); [object, uuid (5F144D5C-A20C-42e7-8F91-4D5CAE430B29), nonextensible , helpstring ( "IDynamics interface"), pointer_default (unique)] interface IDynamics: IUnknown (Speed run () = 0; Speed walk () = 0; Interval jump () = 0;); [uuid (6CC7B329-B92F - 1AB6D7E4CF4D-9CDD-4A8F), the version (1.0), helpstring ( "OLEOBJECT the type 1.0")] (importlib library OLEOBJECTLib ( "stdole2.tlb"); [uuid (62FD0E39-DA84-4B19-BAB0-960A27AC2B71), helpstring ( "OlePaint Class")] coclass OlePaint ([default] interface IPhysiology, interface IPsychics, interface IDynamics););

Yu-Xi requested to observe the above description IDL code and graphics. It is not too difficult.
4) COM object interface principles
In order to standardize the interface mechanism COM, COM developers to the Microsoft issued a COM object interface principles.
(1) the equivalence of the IUnknown interface when we have to wait until the two interfaces indicators, how do I determine which is subordinate to an object. COM interface principles and regulations, with a target of the IID_IUnknown Queryinterface enquiries from IUnknown objective values should be equal. In other words, each object that is the only IUnknown. IUnknown we can judge whether the same guidelines to determine whether they point to the same object.
IUnknown * pUnknown1 = NULL, * pUnknown2 = NULL; pObjectA-> QueryInterface (IID_IUnknown, (void **) & pUnknown1); pObjectB-> QueryInterface (IID_IUnknown, (void **) & pUnknown2); if (pUnknown1 == pUnknown2) (cout << "I am sure ObjectA is ObjectB.";) else (cout << "I am sure ObjectA is not ObjectB.";)
Of course, if not for the IUnknown interface, does not have this limitation. The same object to non-IUnknown interface for value can be different.
(2) interface reflexivity, an interface for its own enquiries should be allowed.
PPsychics is located has been assigned IPsychics interface.
Well pPsychics-> QueryInterface (IID_IPsychics, (void **) & XXX); should be successful.
(3) interface symmetry, as we enquiries from one interface to another interface, from the results we can also query interface to the original interface.
For example:
IPsychics pSrcPsychics =… something * * pTarget = NULL; IDynamics * pDynamics = NULL;
If pSrcPsychics-> QueryInterface (IID_IDynamics, (void **) & pDynamics) to be successful.
Well pDynamics-> QueryInterface (IID_IPsychics, (void **) & pTarget); also very successful.
(4) interface transitivity. If we enquiries from the first interface to a second interface, and from the second interface for the third interface. We should be able to interface enquiries from third to first interface. Other so on.
(5) interface for Irrelevance of time. In a time when we enquiries to an interface, then at any moment should be on this interface.
Tags: com








0 Comments to “COM based component model”
No Comments. Send your comment.
Leave a Reply
You must be logged in to post a comment.