Windows Programming _ sun Xin C ++ lesson19 Dynamic Link Library

Source: Internet
Author: User

Windows Programming _ sun Xin C ++ lesson19 Dynamic Link Library

Highlights of this section:
1. Dynamic and Static Link Libraries
2. view the export function in the dynamic link library and the import function in the program
3. Implicit connections loaded by the dynamic link library
4. external provision of Dynamic Linked Library functions
5. Name adaptation of the function exported from the dynamic link library
6. Export of the entire class and export of some functions of the class
7. Explicit loading and uninstallation of Dynamic Link Library
8. Description of the options when using MFC Appwizard (DLL) to create a DLL Project
//************************************** **************************************** *****************
1. Dynamic and Static Link Libraries
Shows the introduction of dynamic and static Link Libraries:

2. view the export function in the dynamic link library(The premise is that the function has been exported)
Use the program dumpbin.exe of VC program to view or use its tool depends.
Use dumpbin.exe:
Run cmd.exe. first, set up the environment information and run "C: \ Program Files \ Microsoft Visual Studio \ vc98 \ bin \ vcvars32.bat" in cmd.exe"
Then run the dumpbin command to view the information.
View the export status. The command is dumpbin-Exports dll1.dll.
View the import status. The command is dumpbin-imports dlltest.exe> 1.txt(here, the result is displayed in the 1.txt file)
Shows how to view DLL export or EXE import information:

 

3. Implicit connections loaded by the dynamic link library
Note that the Lib file contains the dynamic link library during implicit connection. The LIB file contains the description of the function.
To implicitly connect to the dynamic link library, you need to declare the function prototype. There are three methods:
First: extern int add (int A, int B );
Extern int sustract (int A, int B );
Type 2: _ declspec (dllimport) int add (int A, int B );
_ Declspec (dllimport) int sustract (int A, int B)
Third: include header file method to make programming more Engineering
Connection error:
Linking...
Dlltestdlg. OBJ: Error lnk2001: unresolved external symbol "int _ cdecl add (INT, INT )"(? Add @ yahhh @ Z)
Dlltestdlg. OBJ: Error lnk2001: unresolved external symbol "int _ cdecl sustract (INT, INT )"(? Sustract @ yahhh @ Z)
Copy the dll1.lib file to the dlltest directory. dll1.lib contains the function name and variable name contained in the dynamic link library.
Connect to the Lib file and copy dll1.dll to the current directory (otherwise, a running error occurs ).
4. external provision of Dynamic Linked Library functions
How to let other developers know about the export functions of our dynamic link library can be provided to other developers by providing header files.
Here is a tip. Using macro definition allows function declaration in header files to serve both the program and other developers. Use macro definition to export functions in the following format:
// Dll1.h
# Ifdef dll.pdf API
# Else
# Define dllsort api _ declspec (dllimport)
# Endif
Dllbench API int add (int A, int B );
Dllbench API int sustract (int A, int B );
// Dll1.cpp
# Define dll1_api _ declspec (dllexport)
# Include "dll1.h"
Int add (int A, int B)
{
Return A + B;
}
Int sustract (int A, int B)
{
Return A-B;
}
Here we should understand the expansion process of macro definition. In this program, because the dll1_api is defined, the header file is not included by default,
Then the dll1_api is expanded to _ declspec (dllexport), indicating that this is an export function;
When other programs contain the header file "dll1.h", as long as the dll1_api is not defined, the macro is expanded to _ declspec (dllimport), which indicates the import function. Macro definition reduces the burden of function declaration.
5. Name adaptation of the function exported from the dynamic link library
Different C ++ compilers may adopt different rules for name adaptation, that is, the name of the function in your DLL file has changed externally. Name adaptation may cause an error in program connection.
For example, the dynamic link library is written as follows:
// Dll3.cpp
_ Declspec (dllexport) int add (int A, int B) // when exporting a function, the compiler will modify the name "add"? Add @ yahhh @ Z
{
Return A + B;

}
// The Test Call Code is as follows:
// Explicitly load and detach a dynamic link library
Void cdlltestdlg: onbtnadd ()
{
// Todo: add your control notification handler code here
// Dynamically load the Linked Library
Hinstance hinst;
Hinst = loadlibrary ("dll3.dll"); // enter the correct path name
// Obtain the function address in the dynamic link library
Typedef int (* addproc) (int A, int B); // define the pointer variable receiving function address when needed
// Addproc pfnadd = (addproc) getprocaddress (hinst, "add"); // The name adaptation call of dll3 is invalid.
// Use the adapted name? Add @ yahhh @ Z successfully called
// Addproc pfnadd = (addproc) getprocaddress (hinst ,"? Add @ yahhh @ Z ");

Addproc pfnadd = (addproc) getprocaddress (hinst, makeintresource (1); // The function number is used successfully.
// Note the function pointer type conversion
If (! Pfnadd)
{
MessageBox ("failed to get the function address! ");
Return;
}
Cstring MSG;
MSG. Format ("5 + 3 = % d", pfnadd (5, 3 ));
MessageBox (MSG );
Freelibrary (hinst); // uninstall the dynamic link library
}
Use extern "c" to export the function name. The use of extern "C" solves the problem between C ++ and C language, but extern C cannot be used everywhere for a class member function.
// Dll1.h
# Ifdef dll.pdf API
# Else
# Define dllsort API extern "C" _ declspec (dllimport)
# Endif
Dllbench API int add (int A, int B );
Dllbench API int sustract (int A, int B );
// Dll1.dll
# Define dll1_api extern "C" _ declspec (dllexport)
# Include "dll1.h"
Int add (int A, int B)
{
Return A + B;
}
Int sustract (int A, int B)
{
Return A-B;
}
Indicates the name adaptation that occurs when extern "C" is not used:

It indicates that no name adaptation occurred when using extern "C:

:

However, there is still a problem with the use of extern C. When the function is declared as _ stdcall, the format will still undergo name adaptation, as shown in:

To solve this problem, you can use the def file in the module definition file. No name adaptation will occur when the call conventions are changed to standard calls.
For example, the module definition file used in the program is as follows:
//************************************** **************************************** *****************
// Dll2.def

Library dll2

Exports
Add // function name
Sustract
//************************************** **************************************** *****************
// Dll2.cpp
Int _ stdcall add (int x, int y)
{
Return X + Y;

}
Int _ stdcall sustract (int x, int y)
{
Return x-y;

}
Even if _ stdcall is used in the module definition file, the export function name of the dynamic link library will not change.
However, you must specify the call Conventions when accessing the function. Otherwise, an error occurs. The following code demonstrates that standard calls must also be used when declared as standard calls.
//************************************** **************************************** *******************
// Explicitly load and detach a dynamic link library
Void cdlltestdlg: onbtnadd ()
{
// Todo: add your control notification handler code here
// Dynamically load the Linked Library
Hinstance hinst;
Hinst = loadlibrary ("dll2.dll"); // enter the correct path name
// Obtain the function address in the dynamic link library
// Typedef int (* addproc) (int A, int B); // This format is incorrect when the function declaration in the dynamic link library is a standard call.
Typedef int (_ stdcall * addproc) (int A, int B); // type of the function pointer for standard calls
Addproc pfnadd = (addproc) getprocaddress (hinst, "add"); // defines a function pointer variable to call a function using this pointer.
// Note the function pointer type conversion
If (! Pfnadd)
{
MessageBox ("failed to get the function address! ");
Return;
}
Cstring MSG;
MSG. Format ("5 + 3 = % d", pfnadd (5, 3 ));
MessageBox (MSG );
Freelibrary (hinst); // uninstall the dynamic link library
}
//************************************** **************************************** *****************
If it is not defined as the function pointer type of the standard call, an error occurs. The error message is shown in:

Note one thing: the standard call function must also be used as a standard call convention.
There are several call conventions. This is not discussed for the time being.
6. Export of the entire class and export of some functions of the class
(1) Export the entire class
//************************************** **************************************** *****************
// Export the entire class
# Ifdef dll.pdf API
# Else
# Define dllsort api _ declspec (dllimport)
# Endif
Class dll1_api point
{
Public:
Void output (int x, int y );
Void test ();
};
Void point: output (int x, int y)
{
Hwnd = getforegroundwindow (); // obtain the currently used handle of the caller Process
HDC = getdc (hwnd); // obtain the DC handle
Char Buf [20];
Memset (BUF, 0, sizeof (BUF ));
Sprintf (BUF, "x = % d, y = % d", x, y );
Textout (HDC, 0, 0, Buf, strlen (BUF); // output information
Releasedc (hwnd, HDC );
}
// The test function is only used for exporting and viewing. The actual function is incomplete.
Void point: Test ()
{

}

Shows how to export the entire class function:

//************************************** **************************************** *****************
(2) Export some functions of the class
//************************************** **************************************** *****************
# Ifdef dll.pdf API
# Else
# Define dllsort api _ declspec (dllimport)
# Endif
// Export some functions
Class Point
{
Public:
Void dll1_api output (int x, int y); // exports a member function in the class.
Void test (); // not exported
};

Shows the export function:

//************************************** **************************************** *****************
Use the following code to export a class:
Void cdlltestdlg: onbtnpt ()
{
// Todo: add your control notification handler code here
Point pt;
PT. Output (3, 5 );
}
Shows the running effect:

 

//************************************** **************************************** *****************

7. Explicit loading and uninstallation of Dynamic Link Library
(1)
Load the dynamic link library to make the function loadlibrary. Its prototype is:
Farproc getprocaddress (
Hmodule, // handle to DLL module
Lpstr lpprocname // function name
);
Uninstall the dynamic link library and use the freelibrary function.
Freelibrary reduces the reference count of the dynamic link library by zero. The module uninstalls the address control of the called process.
The dynamic link library that is implicitly loaded can be used in the entire program. However, loading the dynamic link library to the memory through implicit connection increases the process startup time, in addition, many functions in the dynamic link library are not referenced;
Dynamic Loading of the dynamic link library can avoid this. Dynamic Loading will not appear in dumpbin.
(2) Use the getprocaddress function to obtain functions in the Dynamically Loaded Linked Library. Note the function pointer conversion. Otherwise, the following error is thrown:
Error c2440: 'initializing': cannot convert from 'int (_ stdcall *) (void) 'to 'int (_ cdecl *) (INT, INT )'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
The sample code for explicitly loading and detaching a dynamic link library is as follows:
//************************************** **************************************** *****************
// Explicitly load and detach a dynamic link library
Void cdlltestdlg: onbtnadd ()
{
// Todo: add your control notification handler code here
// Dynamically load the Linked Library
Hinstance hinst;
Hinst = loadlibrary ("dll2.dll"); // enter the correct path name
// Obtain the function address in the dynamic link library
Typedef int (* addproc) (int A, int B); // define the pointer variable receiving function address when needed
Addproc pfnadd = (addproc) getprocaddress (hinst, "add"); // defines a function pointer variable to call a function using this pointer.
// Note the function pointer type conversion
If (! Pfnadd)
{
MessageBox ("failed to get the function address! ");
Return;
}
Cstring MSG;
MSG. Format ("5 + 3 = % d", pfnadd (5, 3 ));
MessageBox (MSG );
Freelibrary (hinst); // uninstall the dynamic link library
}
//************************************** **************************************** *****************
8. Description of the options when using MFC Appwizard (DLL) to create a DLL Project
You only need to publish your dynamic link library file, which contains the MFC Link Library.
Make sure that the user machine is installed with the MFC link library when releasing the dynamic link library shared by the conventional Link Library MFC. Otherwise, your link library cannot be correctly loaded.
The difference between the extended Link Library and the common link library shared by MFC is that the extension library must be created when the MFC class is exported.
Summary:
Master the two call methods of the Dynamic Link Library. The export of the dynamic link function includes the export of classes. Pay special attention to the function call conventions in the dynamic link library. errors should be avoided as much as possible.

Related Article

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.