COM Component Design and Application (7) -- Compilation, registration, and call

Source: Internet
Author: User

I. Preface

In the last two times, we used ATL to write the first COM component program. This time, we mainly introduce compilation, registration, and calling methods. Have you downloaded the sample program? If you have not downloaded the file, click here for the vc6.0 user and click here for the vc.net user.

Ii. Compilation

2-1 minimum dependency

 
"Minimum dependency" indicates that the compiler will
Some functions that must be used are statically connected to the target program. In this way, the size of the target file will be slightly larger, but it is more independent and easy to install. On the contrary, the system needs to have ATL. dll
File support. How do I select "minimum dependency? The answer is: Delete the predefined macro "_ atl_dll". For the operation method, see Figure 1 and figure 2.


Figure 1. Setting Method in vc6.0


Figure 2. Setting Method in vc.net 2003

  2-2 CRT Library
 
If the library function of the CRT Runtime is called in the ATL component program, such as square SQRT (), an error may be reported during compilation.
Lnk2001: unresolved external symbol
_ Main ". What should I do? Delete the predefined macro "_ atl_min_crt "! For the operation method, see Figure 1 and figure 2. (This project attribute in vc.net 2003 is called
The minimum CRT used in ATL ")

  2-3 MBCS/Unicode
This is not much to mention. In the predefined macros, _ MBCS or _ Unicode are used respectively.

  2-4 IDL Compilation
 
At the early stage of the design, COM set a goal to achieve cross-language calls. Since it is cross-language, the component interface description must be known in any language environment. What should I do? Use
. H file description? ------ It's really convenient for C programmers to laugh! Basic programmers cried :-(
Therefore, Microsoft uses a new file format-IDL file (interface definition Description Language ). IDL is a text file, and its syntax is relatively simple, like C. Specific IDL
For more information about the file, see the next "COM Component Design and Application (8) Add a new interface". After the IDL is compiled, the binary equivalent library file TLB is generated.
It is provided to other languages for use. Figure 3 illustrates the compilation process of the atl com program:


Figure 3. ATL component program compilation process

Note 1: After compilation, the Type Library exists separately in the form of a TLB file and is also stored in the resource of the target file. Therefore, we can specify both the TLB file and the target file when # import introduces the Type Library in the future;
NOTE 2: As C/C ++ programmers, we are quite happy. This is because after the IDL compilation, We are specially provided with an interface file in the C language format.
NOTE 3: After IDL is compiled, a proxy/stub source code is generated, including dlldata. c, xxx_p.c, xxxps. def, xxxps. mak, we can use nmake. EXE re-compilation to generate the real proxy/stub DLL target file (note 1 ).

Iii. Registration

  Case 1:When we use ATL to write component programs, we are not responsible for registration. After the compilation is successful, IDE will automatically register for us;
  Case 2:When we use MFC to write component programs, since the compiler does not know whether you are writing a COM component, it will not help us automatically register. At this time, we can execute the menu "tools/register control" to register.
  Case 3:When we write an EXE program with the com function, the registration method is to run this program once;
  Case 4:When you want to use the third-party component program, you can run the *** regsvr32.exe filename *** to register the program. In other words, the reverse registration is based on the regsvr32.exe/u file name ";
  Case 5:When we need to execute registration in the program (such as the installation program), then:

Typedef hresult (winapi * freg )();
Tchar szworkpath [max_path];

: Getcurrentdirectory (sizeof (szworkpath), szworkpath); // Save the working directory of the current process
: Setcurrentdirectory (component directory); // switch to the component directory

Hmodule hdll =: loadlibrary (component File Name); // dynamically load the component
If (hdll)
{
Freg lpfunc = (freg): getprocaddress (hdll, _ T ("dllregisterserver"); // get the registration function pointer
// If it is not registered, you can obtain the "dllunregisterserver" function pointer
If (lpfunc) lpfunc (); // execute registration. For simplicity, the return value is not determined.
: Freelibrary (hdll );
}

: Setcurrentdirectory (szworkpath); // switch back to the original process working directory

In the preceding example, the code part for switching the working directory can be simplified in most cases. However, if this component needs to load some required DLL at the same time during loading,
It is possible that it cannot be correctly located due to its own program bug. Well, let's make up for the program we have written. Who makes us good?
Who makes our level higher than him? Who makes us a "eye-catching" on vckbase ......

IV,About component calls

In general, calling a component program involves the following methods:

# Include Method After IDL compilation, XXX. h and xxx_ I .c files will be generated to facilitate the use of C/C ++ programmers. We are so happy that we can use it directly after # include.
# Import Method More common methods, VC will help us produce packaging classes, making our calls more convenient
Method for loading Type Library packages If the component provides the idispatch interface, using this method to call the component is the easiest. I haven't talked about idispatch yet. I can only read later articles.
Method for loading ActiveX packages ActiveX hasn't been introduced yet. Let's talk about it later.

After downloading the sample program, browse the usage items one by one:

Example

Method

Brief Description

1 # Include Completely call components using the most basic API methods, so that you are familiar with the call Principle
2 # Include Most of the APIs use ccombstr to simplify the use of strings.
3 # Include Demonstrate how to use smart pointer ccomptr <>
4 # Include Demonstrate how to use a combination of smart pointer ccomptr and ccomqiptr
5 # Include Demonstrate how to use smart pointer ccomqiptr <>
6 # Include Demonstrate how to release smart pointers
7 # Import How to Use and handle smart pointers ixxxptr, _ bstr_t, and _ variant_t packaged by VC
8 # Import How to Use the imported namespace

Annotations are written in the sample program. Please read carefully and refer to the Function Description of msdn. Here, I will introduce you to "smart Pointers ":
For original operations
Port pointers are troublesome. We need to control reference records, API calls, and exception handling by ourselves. So ATL
Provides two smart pointer template packaging classes, ccomptr <> and ccomqiptr <>.
<Atlbase. h>. Ccomqiptr <> contains
Ccomptr <> all functions, so we can use ccomqiptr completely <>
To use smart interface pointers, the only thing to note is: ccomqiptr <>
Because the overload function of the operator is used, it will automatically call the QueryInterface () function for us. Therefore, ccomqiptr <>
The only drawback is that the iunknown * pointer cannot be defined.

// Smart pointer, which indicates the variable type starting with SP according to the Hungarian naming method
Ccomptr <iunknown> spunk; // correct
// Assume that ifun is an interface type
Ccomptr <ifun> spfun; // correct
Ccomqiptr <ifun> spfun; // correct
Ccomqiptr <ifun, & iid_ifun> spfun; // correct
Ccomqiptr <iunknown> spunk; // error! Ccomqiptr cannot define the iunknown pointer

Assign values to smart pointers:

Ccomqiptr <ifun> spfun; // call the constructor without assigning a value. The encapsulated Internal interface pointer is null.
  
Ccomqiptr <ifun> spfun (potherinterface); // call the constructor. The internal interface pointer value is
// The ifun interface pointer obtained by calling QueryInterface () through the common interface pointer potherinterface
  
Ccomqiptr <ifun> spfun (spotherinterface); // call the constructor. The internal interface pointer value is
// The ifun interface pointer obtained by calling QueryInterface () through spotherinterface.
  
Ccomqiptr <ifun> spfun (punknown); // call the constructor. The ifun interface pointer is obtained by QueryInterface () of iunknown.
  
Ccomqiptr <ifun> spfun = potherinterface; // = Operator overload, meaning the same as above
Spfun = spotherinterface; // same as above
Spfun = punknown; // same as above
  
Punknown-> QueryInterface (iid_ifun, & SP); // you can assign a value through QueryInterface.
  
// After assigning values to smart pointers, you can use conditional statements to determine whether the values are valid or not.
If (spfun) {}// if the pointer is valid
If (null! = Spfun) {}// if the pointer is valid
  
If (! Spfun) {}// if the pointer is invalid
If (null = spfun) {}// if the pointer is invalid

How to call a function using a smart pointer:

Spfun. cocreateinstance (...); // equivalent to the API function: cocreateinstance (...)
Spfun. QueryInterface (...); // equivalent to API function: QueryInterface ()
  
Spfun-> Add (...); // call the interface function of the Internal interface pointer

// Call the QueryInterface () function of the Internal interface pointer. In fact, the effect is the same as that of spfun. QueryInterface (...).
Spfun-> QueryInterface (...);
  
Spfun. Release (); // release the internal interface pointer, and the internal pointer value is null.
Spfun-> release (); // Error !!! Do not use this method.
// Because this call does not clear the internal pointer, The Destructor will be released again (released twice)

Cough... don't talk about it, don't talk about it. Read more books, read more msnd, and read more sample programs. Tired of writing :-(

V. Summary

Stay tuned to COM Component Design and Application (8) ------ how to add the second interface in the ATL component

Note 1: it is a little troublesome to compile the proxy/stub. We will introduce the "out-of-process components" and "Remote components" later. In vc.net 2003, it is relatively simple because the proxy/stub is automatically added to our solution as a separate project.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.