COM component design and application 2 - GUID and interface

xiaoxiao2021-03-18  200

Typedef struct _guid {

DWORD DATA1; // Random

Word Data2; //

Word Data3; // and time related

Byte Data4 [8]; // and NIC MAC

} Guid;

Typedef Guid CLSID; // Component ID

TypeDef Guid IID; // Interface ID

#define refclsid const CLSID &

// Common statement and assignment method

CLSID CLSID_EXCEL = {0x00024500, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0X46}};

Struct __declspec (UUID ("00024500-0000-0000-c000-000000000046))) CLSID_EXCEL;

Class Declspec_UUID ("00024500-0000-0000-c000-000000000046") CLSID_EXCEL;

// Reference method in the registry

{00024500-0000-0000-c000-000000000046}

Indirect the program name with a number, it is indeed a good IDEA that implements the transparency of the component location, and conveniently expands the DCOM (Remote Components). But, but, but, but ..... CLSID has 16 bytes of 128 binary numbers, do you use such a long number? I think that year ... I was still in kindergarten, people designed Sockets, using TCP / IP protocol to communicate network communication. Each computer participating in communication has a 4-byte IP represents the number address, the range is 0, 0, 0, 0 to 255, 255, 255, 255 a total of 4.2 billion addresses. But I didn't expect it. I didn't expect that after INTERNET selected TCP / IP protocol, 42 billion addresses were not worth all over the world. In addition to the people of the labor, there are refrigerators, color TV, rice cooker, mobile phone, laptop ... These need to connect. Give me rice in the office through the network, I can eat ready-made, how happy is it? ! (Note: I am a leader in our wife, so I cook. Cough ...) Due to the former car, Microsoft's design CLSID / IID uses 16 bytes of GUID concept, which is good, 6 billion people around the world, each person assigns 1 billion numbers per second, then it needs to be assigned 180 billion years. Anyway, wait until the earth is not used :-) 3, generate CLSID

If you write component programs using the development environment, IDE will automatically generate CLSIDs; you can write CLSID manually, but don't repeat it with the CLSID that has been generated, so it is seriously recommended; (But Microsoft's CLSID is handmade Writing, this is called "only the state officials"); in the program, the function cocreateGUID () can be generated; using the tool to generate GUID (Note 2); VC6.0 Run: "VC Directory / Common /Tools/guidgen.exe program (you can refer to the method described in the previous article, add this tool program to the development environment, convenient to call). VC.NET version, you can execute in the menu "Tool / Create GUID". Fourth, PROGID concept Every COM component needs to specify a CLSID and cannot be renamed. It uses 16 bytes, which is to ensure that repetition is "impossible" from probability. However, (afraid of the world "but" two words) Microsoft also supports another string name, called PROGID (Note 3). See the contents of the PROGID sub-key of the above-down registry (Note 4). Since CLSID and Progid are actually two different representations of concepts, we can use any one casually in the program. (Some people are annoying, talking is not counted. The purpose of clear guid is to prohibit repetition, but actually allows using progid ?! PROGID is the name of a string, the possibility of repetition is too big. Procedure, I plan to call "Excel.Application", "Excel.Application", "Excel.Application", "Excel.Application", and related functions and related functions below: Function Function Description CLSIDFROMPROGID (), CLSIDFROMPROGIDEX () gets CLSID by Progid. Nothing to say, you can write, check the registration table ProgidFromClsid () get progid by CLSID, the caller is complete, release the progid memory (Note 5) cocreateGuid () Random Generate a guidisequalguid (), ISEqualClsid (), ISEqualiid () compares whether two IDs are equal StringFromClsid (), stringFromGUID2 (), stringFromiid () is obtained by CLSID, IID to get a string of CLSID style in the registry, pay attention to release memory 5. The interface (interface) is here, we already If you know that CLSID or ProGID uniquely represents a component service program, then according to these IDs, you can load the running component and serve the client program. (The method of launching the component program will be introduced). Let's first discuss how to call the function provided by the component? -----interface. As a client programmer, it hopes or says that he only writes once, then you can call any one component without any modifications. for example:

You can embed Excel in Word, or embed Picture, or embed any third party published ActiveX document ... That is, even Word you don't know what to use it will insert in DOC. Dongdong; you can insert an ActiveX in the HTML file, or insert a program script script, ... you write the plugin you can insert into the IE environment. In order to complete your function, you will never let Microsoft modify IE? ! This requirement is a bit difficult, and office development is stagnant. Say, a day old o (General Engineer of Office Project) and small B (General Engineer of VB Project) drink together, old o tapped his trouble to Xiao B: Old o: How can I write the program C , Can call the functions in the program S written by other people? (C represents the client, S represents the program that provides services), small B: Are you drinking? Let S become a DLL, you go to LoadLibrary (), getProcaddress (), ... freeelibrary ()? ! Old o: nonsense! If it is so simple. The problem is, even I don't know what this S is doing? What can you do? How do I call? Small B: Oh ... this is more advanced, but I can't tell you now, because I am afraid that you are impressive. Old o: ~! · # ¥% ... - * ... Small B: Yes, in VB, we have set a standard, this standard allows any VB developers to write a certain feature written by himself The program is placed on the VB toolbar so that he is the same as that of him expands VB. Old o: Oh? Is that what is the use of VBX's abuse? Small B: I am ... don't look at VBX, this thing is not looked, I didn't look at it. But how do you guess? Now there are thousands of VB program enthusiasts write a variety of VBX applets, put them on the Internet, let everyone share it. Old o: Oh ~~~, what is your VBX standard? Small B: 嘿 ... In fact, it is simple, that is, 7 functions must be implemented in VBX, which must be: initialization, release, display, message processing ..., As for what I want to do, I can't manage it. I just call the seven functions I need when I need it. Old o: Oh ~~~, this ... Yes, I have an urgent matter, I will go first. 88, you pay the bill ... small B: Hello! Hello ... I am so anxious what, the wallet has fallen :-) Old o Although I lost the wallet, I still rush back to the office. He began to think ... 1, my program C , To call anyone written program B. Then b must provide the functionality F1 (), F2 (), F3 (), K1 (), K2 (), K1 (), K2 (), K1 (), K2 (), K1 (), K2 (), K1 (), K1 (), K1 (), K2 (), K1 (), K2 (), K1 (), K2 (), K1 (), K2 (), K1 (), K2 (), K1 (), K1 (), K2 (), K1 (), K1 (), K1 (), K1 (), K1 (), K2 (), K1 (), K2 (), K1 (), K2 (), K1 (), K1 (), K1 (), K1 (), K1 (), K1 (), K1 (), K2 (), K1 (), K1 (). 2, BASIC is explained, so its function does not consider writing order, as long as the function name is given, the interpreter can find it.

But I am using C ... 3, there is no function name in C compiled code, only function addresses, so I must improve the entry for the VTAB (virtual function table): Figure 2, VTAB Structure 4, not good enough, need to improve, because all function addresses are placed in a table, not flexible, bad modifications, not easy to expand. Well, there is! Classify the function function: Figure 3, multiple vTab structure 5, the problem is coming, now there is 2 vtab virtual functions, then how can you find another table from a table? Well, I have a way, I ask you to implement a function, and this function address must be placed at the beginning of all tables (the first function pointer in the table), this function is called QueryInterface (), complete from a table Find the function of another table: (except for the queryinterface () function, the other two functions are also completed, called addRef () and release (). After the functionality of these two functions) Figure 4, COM interface structure 6, in order It is convenient to describe it, no longer use the method of the above figure (Figure 4), and the simple style of Figure 5: Figure 5. Simple illustration of the COM interface structure 6. Interface concept 1, function is vTAB The function table provides its address, from another perspective, no matter what language develops, the code generated by the compiler can generate this table. This enables the component's "binary characteristics" to easily implement the cross-language requirements of the components. 2, assuming that there is a pointer type variable to save the first address of VTAB, then this variable is called "interface pointer" (Note 6), when the variable is named, the habit is adopted to start with "I". In addition, in order to distinguish between different interfaces, each interface must have a name, which is the same as the CLSID, using the GUID mode, called IID. 3. Once the interface is published, it cannot be revised again. Otherwise, there will be a forward-compatible problem. This nature is called "interface invariance". 4. There must be 3 functions in the component, queryinterface, addref, release, and three functions also form an interface called "iUnknown". (Note 7) 5, any interface, actually contains the iUnknown interface. As you have come into contact with more interfaces, you will be more "inheritance" to solve the interface. 6. On any interface, call the first function in the table, in fact, call the queryinterface () function, get another interface pointer you want. This nature is called "Delivery of the interface" 7, and the C / C language requires prior to the function declaration, then the component must also provide a header file of the C language. No! In order to make COM have a cross-language ability, it is not necessary to provide a corresponding function interface declaration for any language, but independently provides a declaration called type library (TLB). The IDE environment in each language goes by generating the package you need in your own language according to the TLB. This nature is called "Independence of Interface Declaration" (Note 8). Below is a simulation dialog process between containers and components:

The container negotiated partial component response section 1 According to the CLSID startup component. CocreateInstance () generates an object, performs a constructor, performs an initialization action. 2 Do you have any IunkNown interface? Yes, give you! 3 Well, great, then have you have IPersistStorage interface? (Note 9) IUNKNOWN :: queryinterface is not! 4 is really bad, even this is not. So do you have the IPersistStreaminit interface? (Note 10) IUNKNOWN :: QueryInterface (IID_IPERSISTREAMINIT ...) Ha, this is, give! 5 Good, good, this is similar. You will initialize me now. IPersistStreaminit :: initnew () OK, initialization is completed. 6? it is good! Now you read the data. IPersistStreaminit :: load () read. I have already displayed in the window according to the data. 7 Good, now we have each other to handle the user's mouse, keyboard message ........... 8! Users want to save exit programs. Is your data modified by the user? IPersistStreaminit :: Isdirty () changed, the user has modified. 9. Good, then the user is modified, how much storage space is your data? IPersistStreaminit :: getSizemax () Well, I calculate it ... well, take 500KB. 10 dizziness, do you take this so much space? ! ...... Ok, you can save it. IPERSSTREAMINIT :: Save () Thank you, I have already depated. 11 grace. By you, you. (Note 11) IPersistStreaminit :: releasen :: release () Perform a designer function, delete an object. 12 I should have to quit it ... PostquitMessage () container (or client) is to talk to components, negotiate call. If the component A implements the IA interface, the container will use it. If the component B does not provide an IA interface, it provides an IB interface, then the container will call the IB interface function ... So, the container is fundamentally If you don't need to know what the component is doing, what is the language developed by the component, where the disk position is in the end, it can run normally. Too wonderful! fantastic! How to get a "cool"! Eight, the second round of the small knot, introduced two very important concepts: CLSID and Interface. Since the full art is a concept description, there is no sample program, and the understanding of the reader is not too deep, not thorough.

Don't worry, we will go to the component program design phase. At that time, you will read this article according to the specific program code, go back and read this back article again, didn't read it? Oh ... read again! Your old man will understand :-) How much is the IID of the IDispatch interface? (~~~ Stupid, in the source program, right-click on the go to definition) 2, how many functions have IPicture interface? What is the function? (Don't play! How old are you? I want to display the JPG image in the program, see MSDN to go) I want to know why COM functions always return HRESULT? Want to know how to use BSTR, VARIANT? Want to know how to use memory in COM? Want to know how to use Unicode? ... Well ~~~, I can't tell you now, I will tell you now, I am afraid that you are not impressed! And listen to the decomposition ... I. Preface

The book is back, and in the DOC (Word) composite file, the problem that saves XLS (Excel) data has been solved. Then, then to solve another problem: How do I start the Excel when the Word program reads a composite file? After starting, how do Excel read, resolve, and display XLS data?

Second, CLSID concept

There is a very simple solution, that is, in front of the object data, saves the program name that handles this data. (See the top left of the figure below)

Figure one, concept of CLSID

This is indeed a simple way, but the problem is also very serious. On the computer of "Zhang San", Excel's path is: "c: /office/excel.exe", if this DOC file is copied to "Li Si", and "Li Si" Excel path Yes:

"D: / program files / microsoft office / office / excel.exe", finished :-(

Thus, Microsoft came up with a solution, which is not using a direct path representation, and indirectly describes the processing program path of these object data indirectly using a way to CLSID (Note 1). CLSID is actually a number, or is a 16-byte number. Observe the registry (above), in the HKCR / CLSID / {...} Programs, the LocalServer32 (DLL component is saved in the INPROCSERVER32). The structure of CLSID is defined as follows:

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

New Post(0)