The following is a summary of how to compile the DLL, including some examples from the internet). Thank you for your help. All the examples mentioned below have passed programming tests. Summary 1. LIB: extern "C" int add (int x, int y ); // declare an external function as a C compilation and connection method. 1.1 introduce lib in the program. h: 1) # pragma comment (lib ,".. \ debug \ libTest. lib ") // specify the link to the static library
2) In VC, the tools, options, directories, and library files menus or options can be directly used after the library file path is imported into lib. h. DLL: extern "C" int _ declspec (dllexport) add (int x, int y); // declare the function add as the DLL export function. 1.2 functions in DLL can be divided into two types: (1) DLL export function, which can be called by program; (2) DLL internal function, which can only be used in DLL program, applications cannot call them to import the Dll and cannot call the Add number immediately. There are several steps to call the function: 1.3 first introduce the instance: 1.3.1 production DLL/* file name: lib. h declare the exported function variables and classes in the header file */# ifndef LIB_H
# Define LIB_H/* the function to be called externally must be declared as an export function */
Extern "C" int _ declspec (dllexport) add (int x, int y); // function extern int globalVar; // declare the variable as an external exported variable class _ declspec (dllexport) testClass; // declare this class as an export class # endif/* classTest. h declare the class */# include <stdio. h> class testClass {public: testClass (); void coutData (); protected: private: int ;};
/* File name: lib. cpp can define the export variable function class anywhere, but it must include the header file */# include "lib. h "# include <stdio. h> # include "classTest. h"
Int globalVar = 10; int add (int x, int y) {return x + y;} testClass: testClass () {printf ("output the class! Init... \ n ") ;}void testClass: coutData () {a = 20; printf (" the class 'var is a = % d \ n ", );} /* Lib def: */; use of LIBRARY "testdll"; to comment out LIBRARY testdll // LIBRARY name EXPORTS; use DATA to define the export VARglobalVar DATA // export variable add @ 1 // export function 1.3.2 call:/* Method 1: dynamic call, loadLibrary -- GetProcAddress -- FreeLibrary mode */# include <stdio. h>
# Include <windows. h> typedef int (* lpAddFun) (int, int); // macro-defined function pointer class -------------- 1)
Int main (int argc, char * argv [])
{
HINSTANCE hDll; // DLL handle ------- 3)
LpAddFun addFun; // function pointer ------ 2)
HDll = LoadLibrary (".. \ Debug \ dllTest. dll"); -------- 3)
If (hDll! = NULL)
{
AddFun = (lpAddFun) GetProcAddress (hDll, "add"); ---- 4) // addFun = (lpAddFun) GetProcAddress (hDll, MAKEINTRESOURCE (1 )); // directly reference the sequence number of the export function. The symbols of each export function have been defined in the def file.
If (addFun! = NULL)
{
Int result = addFun (2, 3 );
Printf ("% d", result );
}
FreeLibrary (hDll); ---------- 5)
}
Return 0;
} 1). The statement typedef int (* lpAddFun) (int, int) defines a function pointer type that is the same as that accepted by the add function and returned values. For example.. Net Framework. 2). The instance addFun3 of lpAddFun is defined in the main function. a dll hinstance handle instance hDll is defined in the main function, and DLLaddFun is dynamically loaded through the Win32 Api LoadLibrary. The function pointer addFun is used to call the add function in the DLL. 4 ). in the main function, use the Win32 Api function GetProcAddress to obtain the address of function add in the loaded DLL module and assign it to addFun. The function pointer addFun is used to call the add function in the DLL. 5 ). after the application project uses the DLL, use the Win32 Api function FreeLibrary in the function main to release the loaded DLL module/* Method 2: static call Method */# include ".. \ testdll \ classTest. h "// when calling the export class, you need to include the header file of the class. Is there any other way to make it unnecessary? # Pragma comment (lib ,".. \ debug \ testdll. lib ") extern" C "int _ declspec (dllimport) add (int x, int y); // use dllimport to import functions, and dllexport to indicate function symbols everywhere. extern int _ declspec (dllimport) globalVar; // use dllimport to import the function class _ declspec (dllimport) testClass; int main () {int result = add (2, 3 ); printf ("% d \ n", result); printf ("the global var is: % d \ n", globalVar); testClass test; test. coutData (); return 0;} PS: Note: to export a class, you must set the package Header files containing this class and all header files contained in this header file are added to the calling program. There is another method. Which of the following sections is described below? 2. If you want to be called by other languages, such as VB, You need to modify it with _ stdcall. Example:/* lib. h */# ifndef LIB_H # define LIB_Hint _ stdcall add (int x, int y); # endif/* lib. cpp */# include "lib. h "# include" windows. h "# include" stdio. h "// lib. cpp: The export function bool apientry DllMain (HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {switch (ul_reason_for_call) {case DLL_PROCESS_ATTACH: printf ("\ nprocess attach of dll"); break; case DLL_THREAD_ATTACH: printf ("\ nthread att Ach of dll "); break; case DLL_THREAD_DETACH: printf (" \ nthread detach of dll "); break; case DLL_PROCESS_DETACH: printf (" \ nprocess detach of dll "); break;} return TRUE;} // when outputting a function using any method, make sure to use the _ stdcall call Convention. The _ stdcall call Convention is used to call Win32 API functions. // _ Stdcall pushes the parameter into the stack in reverse order (from right to left) int _ stdcall add (int x, int y) {return x + y ;} /* lib def */; lib. def: Export DLL function LIBRARY LIBEXPORTSadd @ 1 call: # include "stdafx. h "# include" windows. h "typedef int (_ stdcall * lpAddFun) (int, int); int main (int argc, char * argv []) {HINSTANCE hDll; lpAddFun addFun; hDll = LoadLibrary (".. \ Debug \ dllTest. dll "); if (hDll! = NULL) {addFun = (lpAddFun) GetProcAddress (hDll, "add"); // or addFun = (lpAddFun) GetProcAddress (hDll, MAKEINTRESOURCE (1 )); // MAKEINTRESOURCE directly use the serial number if (addFun! = NULL) {int result = addFun (2, 3); printf ("\ ncall add in dll: % d", result);} FreeLibrary (hDll);} return 0 ;} the following part is reprinted:
DLL functions:
The dynamic link library defines two types of functions: the export function and the internal function ).
Export functions can be called by other modules. Internal functions are used within the DLL program that defines them.
The following methods are used to output functions:
1. Traditional Methods
Specify the function or variable to be input in the EXPORT section of the module definition file. The syntax format is as follows:
Entryname [= internalname] [@ ordinal [NONAME] [DATA] [PRIVATE]
Where:
Entryname is the name of the output function or data to be referenced;
Internalname is the same as entryname;
@ Ordinal indicates the sequence number (index) in the output table );
NONAME is used only when output by sequence number without entryname );
DATA indicates that a DATA item is output. The program that outputs DATA using DLL must declare this DATA item as _ declspec (dllimport ).
In the preceding items, only entryname is required, and other items can be omitted.
For "C" functions, entryname can be equivalent to the function name, but for "C ++" function member functions, non-member functions)
Entryname is the modifier name. You can get the modifier of the function to be output from the. map image file, or use
Get DUMPBIN/SYMBOLS and write them in the output module of the. def file. DUMPBIN is a tool provided by VC.
If you want to output a "C ++" class, write the data to be output and the modifier of the members to the. def module definition file.
2. Output in the command line
Specify the/EXPORT command line parameter for the LINK program LINK and output the relevant functions.
3. Use the modifier _ declspec (dllexport) provided by MFC)
Add the _ declspec (dllexport) modifier before the declaration of the function, class, and data to indicate the output. _ Declspec
(Dllexport) in the case of C call conventions and C compilation, you can remove the underline prefix of the output function name. Extern "C" makes
It is possible to use the C compilation method. To define the "C" function under "C ++", add the extern "C" keyword. Use extern "C"
Indicates that the function is compiled in C. The output "C" function can be called from the "C" code.
For example, a C ++ file contains the following functions:
Extern "C" {void _ declspec (dllexport) _ cdecl Test (int var );}
The output function is named Test.
MFC provides some macros for this purpose.
AFX_CLASS_IMPORT :__ declspec (dllexport)
AFX_API_IMPORT :__ declspec (dllexport)
AFX_DATA_IMPORT :__ declspec (dllexport)
AFX_CLASS_EXPORT :__ declspec (dllexport)
AFX_API_EXPORT :__ declspec (dllexport)
AFX_DATA_EXPORT :__ declspec (dllexport)
AFX_EXT_CLASS: # ifdef _ AFXEXT
AFX_CLASS_EXPORT
# Else
AFX_CLASS_IMPORT
AFX_EXT_API: # ifdef _ AFXEXT
AFX_API_EXPORT
# Else
AFX_API_IMPORT
AFX_EXT_DATA: # ifdef _ AFXEXT
AFX_DATA_EXPORT
# Else
AFX_DATA_IMPORT
If a macro such as AFX_EXT_CLASS is used in the implementation of the DLL application, it indicates that the output is defined because _ AFX_EXT
This option is usually specified in the identifier parameter of the compiler/D_AFX_EXT). If it is used in an application that uses DLL, it indicates the input
_ AFX_EXT is not defined ).
To output the entire class, use _ declspec (_ dllexpot) for the class. to output the member function of the class, use
_ Declspec (_ dllexport ). For example:
Class AFX_EXT_CLASS CTextDoc: public CDocument
{
...
}
Extern "C" AFX_EXT_API void WINAPI InitMYDLL ();
Among these methods, the third method is recommended for ease of use; the second is the first method. If output by sequence number, the call efficiency will be higher;
The second type.
Vi. module definition file (. DEF)
The module definition file (. DEF) is a text file consisting of one or more module statements used to describe the DLL attributes. Each DEF file must at least
The following module definition statement must be included:
* The first statement must be a LIBRARY statement that specifies the DLL name;
* The EXPORTS statement lists the names of the exported functions. The modified names of the functions to be output are listed under EXPORTS.
The name of the defined function is exactly the same, so that a function name without any modification is obtained.
* You can use the DESCRIPTION statement to describe the usage of the DLL (this sentence is optional );
* ";" (Optional) Comment on a row ).
VII. Relationship between the DLL program and the program that calls its output function
1. Relationship between dll and process and thread
The DLL module is mapped to the virtual address space of the process that calls it.
The DLL Memory is allocated from the virtual address space of the calling process and can only be accessed by the thread of the process.
The DLL handle can be used by the calling process, and the call Process Handle can be used by the DLL.
DLL uses the stack of the calling process.
2. About shared data segments
The global variables defined by DLL can be accessed by the calling process; The DLL can access the global data of the calling process. Use each
All processes have their own DLL global variable instances. If multiple threads concurrently access the same variable, you must use the synchronization mechanism.
DLL variable. If you want each Thread using the DLL to have its own value, you should use the local Thread storage (TLS, Thread
Local Strorage ).
Add pre-compiled commands to the program, or set the data segment attribute in the project settings of the development environment.
These variables assign initial values. Otherwise, the compiler will place the variables without initial values in a data segment called uninitialized.