COM objects are encapsulated entities that provide services to users. This should be similar to the Class Object in C ++. But sometimes the COM object is treated as the class that provides services. The COM Object also encapsulates the data and provides interfaces. But there are some differences with the class. The data in the class can be declared as public, and then the user can directly access these data members. However, you cannot directly access the data of a COM object. You can only access the data through an interface (if such an interface is provided. Generally, a COM interface refers to a group of interfaces that provide services. At first, I was not used to this definition. Because c ++ does not have the interface concept at all, but such languages as Java have the interface concept. The COM interface can be understood according to the Java interface (it is a good thing to know a few more languages ). The definition method in C ++ is generally implemented using abstract classes. All the functions are purely required functions, and all are implemented by sub-classes. For example, an interface is defined as follows:
1 struct ICalc2 {3 virtual long __stdcall add(long a, long b) = 0;4 virtual long __stdcall minus(long a, long b) = 0;5 virtual long __stdcall times(long a, long b) = 0;6 virtual long __stdcall devide(long a, long b) = 0;7 };
When using the COM component, the customer does not know the exact object of the COM component. Therefore, the COM component must register the registry. However, the customer still needs some identifier to access the COM component and use the COM object. The first direct idea is to get a name. However, in this case, Company A makes a plug-in called calculator, and Company B also makes a plug-in called calculator. Even wangcai at home can write a plug-in called calculator. So this method is not very good. To solve this duplicate problem. Microsoft decided to use guid to identify the plug-in. GUID is a 128-bit random number. Everyone is random. Aren't you afraid of the same number? Well, there is a possibility, but the probability is too low. In theory, if a computer generates guids per second, it can ensure that there will be no duplicates in (of course, in the probability sense, I don't know how to calculate it ). The probability of duplicate guids is very low and can be safely used. Each COM object is identified by a guid, which is generally called clsid. Each COM interface also has a guid, which is generally called an IID. In C ++, The GUID is defined as follows:
1 typedef struct _GUID2 {3 DWORD Data1;4 WORD Data2;5 WORD Data3;6 BYTE Data4[8];7 } GUID;
According to the COM specification, as long as the user obtains a COM object interface, the user can obtain other interfaces of the COM object through it (if any ). Before a user uses a COM object, the user needs to create a COM Object (I think the COM Object Name is really annoying. The book says that the COM Object refers to the class that provides services, it also refers to the object instantiated based on this class ). To create a COM object, you must allocate some resources. After these resources are used up, you must release the object. Therefore, each COM object has a count. When the Count value is 0, the COM object is destroyed. When another pointer obtains this COM object, the count will be increased. If a pointer releases control over this COM object, the count will be reduced by one. This counting method is similar to a smart pointer. However, the Count of COM objects is not as intelligent as the pointer, and sometimes needs to be released manually. Therefore, users are responsible for releasing resources. Based on the above statement, we need an interface for getting all other interfaces, adding the counting interface and reducing the counting interface. The iunknown interface provided by COM already provides these three interfaces (note: the COM interface generally refers to a group of interfaces rather than an interface ). In fact, all com interfaces must be inherited from iunknown. Iunknown provides the QueryInterface, addref, and release interfaces. The definition of C ++ is as follows, but the actual definition is difficult to write. Here is a simple method.
1 class IUnknown2 {3 public:4 virtual HRESULT __stdcall QueryInterface(const IID &iid, void **ppv) =0;5 virtual ULONG __stdcall AddRef() =0;6 virtual ULONG __stdcall Release() = 0;7 }
Iunknown is an API that also has an IID. The IID of iunknown is iid_iunknown = commandid -0000-0000-c000-000000000046. The rest is the interface defined by the user. You can also define multiple interfaces. Finally, the classes that provide services integrate these interfaces to form a class that can be used to create COM objects. For example, the following icequal is an interface, and ccequal is a class that implements services.
1 class ICalc : public IUnknown 2 { 3 public: 4 virtual long __stdcall add(long a, long b) = 0; 5 virtual long __stdcall minus(long a, long b) = 0; 6 virtual long __stdcall times(long a, long b) = 0; 7 virtual long __stdcall devide(long a, long b) = 0; 8 }; 9 10 class CCalc : public ICalc11 {12 public:13 CCalc();14 ~CCalc() = default;15 16 public:17 //IUnknown interface:18 virtual HRESULT __stdcall QueryInterface(const IID &iid, void **ppv) override;19 virtual ULONG __stdcall AddRef() override;20 virtual ULONG __stdcall Release() override;21 22 //ICalc interface:23 virtual long __stdcall add(long a, long b) override;24 virtual long __stdcall minus(long a, long b) override;25 virtual long __stdcall times(long a, long b) override;26 virtual long __stdcall devide(long a, long b) override;27 28 private:29 long m_lRef;30 };
Override is the keyword provided by the C ++ 11 standard.
This blog will be written here first, and we will continue to write it later, but now we have to go back to the dormitory. We will continue to write this blog tomorrow or the day after tomorrow.
PS: the blogger is also a cainiao. He has recently started to write a technical blog. If you find any mistakes, please click it and point out the mistakes.
Study Note 2 of "com Principles and Applications" -- Implementation of COM objects and COM Interfaces