The theoretical knowledge that COM programming must be made with VC
-
Lostall
This article is to see the beginners, try to write more popular and easy to understand, and try to avoid programming details. It is fully based on
I wrote my own learning, and if there is a technical mistake, please pay more.
1. Why use com
2. Use VC for COM programming, it is necessary to master which COM theory knowledge
First, why use com
Software Engineering has developed to today, from the beginning of structured programming, to object-oriented, and now come to COM, programming,
There is only one standard, that is, it is desirable that the software can be as tired as the cocific block, which is assembled, not a little bit.
Structured programming is in the form of a function block, by dividing a software into many modules, each module completes different work
Can, try to achieve high-level patching, this is already a good start, we can give different modules to different people
Do it, then in one, this already has the concept of assembly. The core of software engineering is to modular, the ideal situation
It is 100% co-gauge 0%. The development of the entire software is also walking in this direction. Structured programming is just one start.
The next step has an object-oriented programming, which is a huge progress relative to the functional structure. We know
Nature is composed of a variety of different things, and there is a complex thousands of relationships between things, but
The connection between things, interaction, our world is a vitality. We can think that in nature
The secondary thing is a concept that is stable, and the connection between things is varied, sports. Things should be this
The essence of the world. Object-oriented focus is something, this is this stable concept. Everything has its own inherent
Attributes have their own inherent behavior, these are things inherent in the matter itself, and the object-oriented method is to describe this
Stable things. The function-oriented modular method It is a connection between things, it can't see the concept of things in their eyes.
It only pays attention to the function, have we always think about this function when the module is divided? Few people
I think, a function is a function, this feature must contact some things, we have not to grasp the things itself.
Only consider how to interact between things. To put it bluntly, this is called this at the end, and it is also called an emergency, because
In order not our wisdom, just because we don't think much about one step. Functional structured methods because it pays attention to
The connection between things, while the contact is changed, the things itself may not change, and the connection is very likely to change
If you change, contact it, that is another world, that is another function. If we use object-oriented methods, I
They can change to death, as long as the things are described in advance, we have to change these classes.
Just reuse our class libraries, and process-oriented methods because it constructs a unstable world, so a little small
Changes may also cause the entire system to change. However, the object-oriented method still has problems, and the problem is the method of reuse. take
The basis of the building block software constructor is to have many a variety of reusable components, modules. What we first think of
Class library, because the direct result produced by the object-oriented method is a number of classes. But reuse of class libraries is based on source code.
, This is its significant defect. First, it limits the programming language, your class library is always written in a language, then you can't
I have used it in other languages. Second, you must recompile each time, only compiled with your own code.
Generate an executable. This is nothing, the key is that your EXE has been generated after the development is complete. If you have a new class library, you have a new class library. Fast, and you are
I want to use this new version of the class library into your own program, then you must recompile, rebugging! This is ideal from us
The building block software constructor also has a certain gap. In our idea, I hope to take a module and then change a new module.
Very convenient, but now it is necessary to recompile, but also to raise a lot of risks, because you may have to change your own
Code. Another reuse method naturally thought of the way is a DLL. Windows is a DLL everywhere, it is Windows
The foundation, but the DLL also has its own shortcomings. Summarize it at least four points. (1) Function is renamed. DLL is one
One function, we call functions through the function name, what should I do if there is a renameful function in the two DLLs? (2) each compilation
The name is incompatible with the name of the C function. For C functions, the compiler is generated according to the function of the function.
The name of the DLL reservoir is this modification, but different compilers produce modified methods are different, so you are in VC
The DLL written in the BC can not be used in the BC. However, you can also use extern "C"; to emphasize the use of standard C function characteristics, close
The modification function, but it also lost the C overload polymorphism. (3) path problem. Put it under your directory, others
The procedure can not be found, put it in the system directory, may have a problem. And true components should be available anywhere
You can even don't need to consider this problem at all, users don't need to consider this problem. (4) DLL and EXE dependence. We generally use hidden
The way the way is connected, it is programmed to indicate what DLL, this way is simple, it is tied to DLL when compiling
It is together. If the DLL releases a new version, we must also re-link once, because the address of the function in the DLL can be
Can have changed. The DLL disadvantage is the advantage of COM. First we have to grasp a point, COM and DLL are
Based on binary code reuse, it does not exist when the library is reused. Another key point is that COM itself is also a DLL,
Beneficial to be ActiveX control. ICX is actually a DLL, so the DLL has a great advantage in reuse, but we
By formulating complex COM protocols, the mechanism of COM itself changes the reuse method, with a new method to use DLL, come
Overcome the defects in which the DLL itself, thereby achieving higher levels of reuse methods. COM has no rename, because it is not a pass
The function name is used to call the function, but through the virtual function table, there is naturally no function name modification. Path problem is not repusive
Because it is to find the component by checking the registry, where it is possible, even in other machines. Nor
Considering the dependence of EXE, both of them are loosely combined, and can easily replace a new version of the assembly.
This, and the application is mixed.
Second, use VC for COM programming, what kind of COM atrial knowledge must be mastered
I have seen many people learn COM. After reading a book, I feel that I know the principle of COM. COM is alive, but
I don't know how to make a program, I have this situation, I have experienced this stage. To learn COM base
The principle, the book I recommend is "COM technology insider". But only such a book is far less, our ultimate goal is to learn how to use COM to program, not desperately study the mechanism of COM itself. So I personally feel that the basic principle of COM is not
It takes a lot of time to chase the bottom, there is no need, it is something that is not good. In fact, we only need to master a few keyings.
It's enough to read. Here I lists some of my own key concepts I think that it is necessary to use VC programming. (Here
Both COM programming methods under C language conditions)
(1) The COM component is actually a C class, and the interface is a pure empty class. Components are derived from the interface
We can simply describe COM with a pure C grammatical form:
Class IOBJECT
{
PUBLIC:
Virtual function1 (...) = 0;
Virtual function2 (...) = 0;
....
}
Class MyObject: Public IObject: Public IObject
{
PUBLIC:
Virtual function1 (...) {...}
Virtual function2 (...) {...}
....
}
Is it clear? IObject is the interface we often say, MyObject is the so-called COM component. Remember to remember the interface
Pure virtual class, the functions it contains are pure virtual functions, and it does not have a member variable. And COM components are from these pure
The class inherited the derived class, which implemented these virtual functions, just this. It can also be seen from the above, COM components are
C -based, especially important is the concept of virtual functions and polymorphism, all functions in COM are virtual functions, must pass
Take the virtual function table vtable to call, this is incapable of being important, and must keep in mind in mind. In order to let everyone know
What is the virtual function table looks like, from the COM technology inside: Copy below:
(2) The COM component has three most basic interface classes, which are IunkNown, IclassFactory, Idispatch.
The COM specification specifies any components, and any interface must be inherited from iUnknown. IUNKNOWN contains three functions, respectively.
QueryInterface, addRef, release. These three functions are extremely important, and their arrangement is not
can be change. QueryInterface is used to query other interfaces implemented by the component, and it is white to see the father of this component.
What are the interface classes in the class, and addRef is used to increase the reference count, and Release is used to reduce the reference count. Quote count
It is a very important concept in COM. It is very simple to say that the COM component is a DLL.
When you use it, you have to put it in memory. On the other hand, a component is not only for you.
There will be many programs to use it at the same time. But in fact, the DLL is only loaded once, ie there is only one COM component in memory.
Who is the COM component released? Is it a customer program? It is impossible, because if you release the component, how is it used,
So you can only be responsible by COM components. So there is a reference to the reference count, COM maintains a count, record the current
How many people are using it, plus a count once a call, and a less customer will use it to reduce one, when the last customer is released
It's time, COM knows no one has used it, and its use is over, then it will be released.
The reference count is a place that is very easy to make mistakes in COM program, but fortunate in various types of libraries of VC have basically
The call of addref is implied. In my impression, I have never called AddRef when I have programmed, and we only need to call Release Release when appropriate. At least two times, I have to remember to call Release, the first one is called.
After queryinterface, the second is to call any function that gets a pointer to an interface, remember MSDN
To determine if addRef is called inside a function, if it is, the responsibility of the call Release is to return you.
IUNKNOWN's implementation of these three functions is very standard but also very cumbersome, easy to make mistakes, fortunately, we may always
You don't need yourself to achieve them.
The role of iClassFactory is to create a COM component. We already know that COM components are actually a class, then we flat
How often is it to instantiate a class object? Is the 'new' command! It's very simple, the COM component is the same. Who is
Come to New it? It is impossible to be a client program because the client cannot know the class name of the component, if the customer knows the group
The reusability of the component of the component is a big discount, and in fact the customer program only knows a representative.
The 128-bit digital string of the component is, this will be introduced. So customers can't create components themselves, and consider one
Next, if the component is on a remote machine, can you also get an object? Therefore, the responsibility of creating components is handed over.
A separate object, this object is a class factory. Each component must have a class with related to it, this class is known
How to create a component, when the customer requests an instance of a component object, actually gives the request to the class, by the class factory
Create a component instance, then give the instance pointer to the client. This process is special when the process is created across processes and remotely.
Used, because it is not a simple New operation, it must be scheduled, and these complex fucks
Working to the class object of the work. The most important function of IclassFactory is CreateInstance, as the name
That is to create a component instance, in general, we will call it directly, the API function is packaged for us, only
In some special circumstances, we will call it himself. This is also the benefit of VC writing COM components, making us more
Control opportunities, while VB gives us a chance to be too rare.
Idispatch is called a scheduling interface. What is its role? There are still many other languages in this world, such as VB,
VJ, VBScript, JavaScript, etc. It can be said that if there is so many messy languages in this world, then
There will be no IDispatch. :-) We know that the COM component is a C class. It is a virtual function table to call the function, for VC
It is not a problem, this is designed for C , before VB can't, now VB can also use pointers, or
Call the function via vTable, VJ can also, but some languages don't work, that is, scripting language, typical
VBScript, JavaScript. The reason is that they do not support pointers, and even the pointers can not be used with polymorphism.
Sex, how to adjust these virtual functions. Oh, there is no way, you can't set these scripting languages, now on the webpage
It is these scripting languages, and distributed applications are also a major market for COM components, which have to be subject to these scripts.
The language calls, since the virtual function table is in the way, we can only find another law. Time to make a hero, IDispatch should
Born. :-) Scheduling Interfaces each attribute each attribute is numbered, and the client will pass these numbers to the IDispatch interface when the client program is called, and the idispatch calls the corresponding function according to these numbers, only
Here. Of course, the actual process is much more complicated. When you give a number, you can let others know how to call a function.
Is it a heaven, you have to let others know what parameters you want to call? What is the parameter type, and return?
Things, but to deal with these issues in a unified way is something that is a headache. Main function of IDispatch interface
It is invoke, both the client calls it, then invoke calls the corresponding function, if you see the implementation of MS's class library
Invoke's code will amaten the complex it is achieved, because you have to consider the type of parameter type, fortunately, we don't
It is necessary to do this, and may never have this opportunity. :-)
(3) Dispinterface interface, DUAL interface, and Custom interface
This small festival is placed here that it does not seem to be appropriate because it is used in ATL programming. I am mainly going to talk about it here.
The benefits and disadvantages of the automation interface, use these three terms to explain it may be better, and will meet later later
They will explain them in a popular way, it may not be so accurate, as if you use pseudo code to describe the algorithm.
same. - :)
The so-called automation interface is an interface implemented with iDispatch. We have explained the role of iDispatch, it's good
It is a scripting language like VBScript, JavaScript can also use COM components, so that it is basically unrelated to the language.
Its shortcomings have two main points, the first is that the speed is slow. This is obvious, the table is turned off through the virtual function.
The function can be called, and the invoke is equal to the middle transfer, especially the function parameters need to be converted into one.
The format of the specification is to call the function and delay a lot of time. So, if it is not forced, we all want to use vTable
The function is called to obtain high efficiency. The second disadvantage is to use only a predetermined so-called automated data type. Such as
If you don't have iDispatch, what type of data we can use, the VC will automatically generate the corresponding scheduling
Code. And use the automation interface is not ok, because the implementation code of Invoke is written in advance, and it can't pre-
From all the types we have to use, it can only write its processing code according to some common data types, and it also
To consider the data type conversion problem between different languages. Therefore, the scheduling code generated by the VC automation interface is only available for it.
These data types are specified, of course, these data types are already rich enough, but they cannot meet custom data structures.
Claim. You can also write the scheduled code to handle your custom data structure, but this is not an easy task.
Taking into account the disadvantages of Idispatch (it still has a shortcomings, it is using trouble, :-)) Now generally recommend writing double pick
The port assembly is called the DUAL interface, actually the interface inherited from IdisPatch. We know that any interface must be from
IUNKNOWN inherits, the IDispatch interface is no exception. The interface inherited from idispatch is actually equal to two bases.
Class, one is iUnknown, one is iDispatch, so it can call the component in two ways, can pass
IUNKNOWN invokes the interface method with virtual functions, or can be called via Idispatch :: Invoke.
This has a lot of flexibility, which can be used in the C environment can also be used in scripting languages, while meeting
The needs of all aspects.
Compared to comparison, Dispinterface is a pure automation interface that can be simply regarded as an IDispatch interface (although it is actually not), this interface can only be called, COM components Generally
It is this form of interface.
The Custom interface is a class derived from the iUnknown interface. It is clear that it can only call the interface with the virtual function table.
(4) There are three kinds of COM components, within the process, local, remote. The interface pointer and function parameters must be scheduled for the last two.
COM is a DLL, which has three operating modes. It can be within the process, that is, and the caller is in the same process,
With the caller on the same machine but in different processes, it can also simply and the caller on both machines.
Here is a fundamental point to keep in mind, that is, the COM component is just a DLL, which is still running, must
There is a process like a father who takes care of it, that is, the COM component must be in a process. Who is acting as a guardian?
Let me talk about the problem of scheduling. Scheduling is a complex issue, and I don't know this problem with my knowledge. I am just general.
Sexual talks about several of the most basic concepts. We know that for Win32 programs, each process has 4GB virtual address empty
Each process has its own addressing, the address of the same data block in different processes is likely to be different.
So there is an address conversion problem between the processes. This is the scheduling problem. For local and remote processes, DLL
And the customer program is in different addressing spaces, so the interface pointer to the client must be scheduled. Windows
It has been provided with ready-made scheduling functions, which does not require our own complex things. For remote components
The parameter transfer of the function is another dispatch. DCOM is based on RPC, to pass data between networks must comply with the standard
The quasi-online data transfer protocol, before the data is passed, first pack it, then unpackage after passing to the destination, this process is tune
Degree, this process is very complicated, but Windows has already made everything is done well, in general, we don't need to
I have to write a scheduled DLL.
We just said that a COM component must be in one process. Components for local mode are generally in the form of EXE,
So it itself is already a process. For remote DLL, we must find a process, this process must contain
Scheduling code to achieve basic scheduling. This process is DLLHOST.EXE. This is a COM default DLL agent. In practice
In distributed applications, we should use MTS as a DLL agent because MTS has a strong function, which is specifically used for
Manage tools for distributed DLL components.
Scheduling from us, it seems very far away, we rarely pay attention to it when we program, this is one of the advantages of COM, both flat
Nothing, no matter what you are remote, local or within processes, the programming is the same, all details are from COM themselves
Have it, so we don't have to study this problem, as long as you have a concept, of course, if you have a schedule
The special requirements you need to understand the entire process of scheduling, here is recommended, "COM technology insider", this
It is definitely a good book for scheduling.
(5) The core of the COM component is IDL.
We hope that the software is a block assembled, but it is impossible to be unregulated, always abide by certain
Standards, how to closely and unconscious cooperation between each module must be developed in advance.
Van, this specification is the interface. We know that the interface is actually purely false, it defines a lot of pure virtual letters inside.
Number, waiting for a component to implement it, this interface is the key that two completely unrelated modules can be combined.
Imagine if we are an application vendor, we need to use a module in our software, we don't have time to develop, so we think that the market is looking for a module, how do we find it? Maybe we
This module that needs has been standard in the industry. Some people have developed standard interfaces, there are many component tools.
Commerce has implemented this interface in their own components, then the goal we find is that these groups have implemented interfaces.
Parts, we don't care where to come from, what other features, we only care about whether it is very good to achieve us
Develop a good interface. This interface may be the standard of the industry, or it is only the coordination of you and several manufacturers.
Discuss, but in short it is a standard, it is the foundation of your software and others can be combined, and is COM components.
Communication standard.
CoM has language-independent, which can be written in any language or call on any language platform. But now
Those we have been talking about COM in a C environment, how is its language irrelevant? Or otherwise
Say, how can we define the interface in a language-independent way? In front, we define them directly with pure empty classes.
, But obviously can't, in addition to C , who is also recognized? It is for this consideration, Microsoft decides to use IDL to define
interface. To put it bluntly, the IDL is actually a language that everyone knows, uses it to define the interface, no matter which one
It knows it on the language platform. We can imagine the ideal standard component mode, we always start from IDL,
First use IDL to form all interfaces, then assign different people to achieve the task of the interface, some people may be good for use VC,
Some people may be as good as VB, this does not matter, as a leader, I don't care, I only care about you finally
give it to me. This is a good development model, you can use any language, you can also appreciate any language.
Your development results.
(6) How the COM component runs, that is, how COM runs.
This part we will construct a minimum frame structure that creates a COM component, then take a look at what is the internal processing process.
Iunknown * punk = null;
IObject * pObject = null;
Coinitialize (NULL);
CocreateInstance (CLSID_Object, Clsctx_inproc_server, null, IID_IUNKNOWN,
(void **) & punk);
Punk-> queryinterface (IID_IOJBECT, (Void **) & POBJECT);
punk-> release ();
POBJECT-> FUNC ();
POBJECT-> Release ();
Couninitialize ();
This is a typical creation of a framework for COM components, but my interest is in cocreateInstance, let us
Let's see what it has done inside. The following is a pseudo code that it implemented inside:
CoCreateInstance (....)
{
.......
IclassFactory * pclassfactory = null;
CogetherClassObject (CLSID_Object, ClsctX_inproc_server, null, iid_iclassfactory,
(void **) & pclassFactory;
PclassFactory-> CreateInstance (NULL, IID_IUNKNOWN, (VOID **) & PUNK);
PCLASSFAACTORY-> Release (); ........
}
The meaning of this paragraph is to get the class object, and then create a component through the class factory to get an IunkNown pointer.
Continue to go deep into one step and see the internal pseudo code of CogetClassObject:
CogetherClassObject (.....)
{
// By checking the registry CLSID_Object, you know the location of the component DLL, file name // load the DLL library // Use the function getProcAddress (...) to get the function of the function dllgetClassObject in the DLL library. // Call DLLGETCLASSOBJECT
}
DllgetClassObject is dry, it is used to get a class object. You can only create components before you get the class.
Here is the pseudo code of DllgetClassObject:
DllgetClassObject (...)
{
......
CFActory * pfactory = new cfactory;
// class factory object
Pfactory-> QueryInterface (IID_ICLASSFAACTORY, (VOID **) & PCLASSFAACTORY
// Query the IclassFactory pointer
Pfactory-> Release ();
......
}
The process of COGETCLASSOBJECT has been here, now returns COCREATEINSTANCE to see CreateInstance
Pseudo code:
Cfactory :: createInstance (.....)
{
...........
COBJECT * POBJECT = New COBject;
// Component object
POBJECT-> QueryInterface (IID_IUNKNOWN, (VOID **) & PUNK);
POBJECT-> Release ();
...........
}
The picture below is an example of Copy from COPY from the COM technology, which can be clear from the figure to see the entire CocreateInstance
Process.
(7) Four functions necessary for a typical self-registered COM DLL
DllgetClassObject: Used to get a factory pointer
DllRegisterServer: Register some necessary information to the registry
DllunRegisterServer: Uninstalling Registration Information
DllcanunloadNow: This function will be called when the system is idle to determine if the DLL can be uninstalled.
There is also a function of DLL is DLLMAIN. This function does not require it in COM, but the group generated in VC
Automatically contains it, its role is mainly a global instance object.
(8) Important role of registry in COM
First of all, we must know the concept of GUID. All classes, interfaces, and type libraries in CoM use guid to uniquely identify, and Guid is a
A 128-bit string that the GUID generated according to the special algorithm can be guaranteed to be unique worldwide.
The COM component is created, and the query interface is performed by the registry. With the registry, the app doesn't know
The component's DLL file name, location, only need to find according to CLSID. When the version is upgraded, just change it.
The registry information can be unknown to the new version of the DLL.
This article is a coated duck in this person. It is not very comprehensive, and there are many useful experiences that have not been written.
If there is time, you are interested in writing. I hope this article will bring you a little use, then I have no white in the morning.
Fee. - :)