MFC (Dynamic Link Library programming, Sun Xin C ++ 19th lecture notes)

Source: Internet
Author: User
Tags export class

1. dll introduction, dynamic library, and static library. The dynamic library saves disk space and the static library is large. You can write DLL files in multiple languages. The dynamic library can be loaded in two ways: implicit call and dynamic addition!

 

2. Create a dll1 DLL project, add a source file named dll1.cpp, and add the add and subtract functions. Note that _ declspec (dllexport) must be added before the function name and compiled. Dumpbi
-Exports dll1.dll: Check the exported function and find that the function name has been changed? Add @ yahhh @ Z. This is called name smash, which is implemented to support function overloading.

 

3. Compile a program test DLL named dlltest. Based on the dialog box, place two buttons add and subtract to respond to the new message and call the add and subtract functions of the DLL. Declare the function before using these two functions, // extern
Int add (int A, int B );

// Extern int subtract (int A, int B );

Copy dll1.lib and dll1.dll to the current directory! In addition, you also need to add dll1.lib to project-> setting-> link-> Object/library. This method is called implicitly! OK! Dumpbin
-Imports dlltest.exe: view its input information. You can see that it has loaded dll1.dll. You can also use the depends program to view the DLL files required by the program! In addition to extern, you can also use // _ declspec (dllimport)
Int add (int A, int B );

// _ Declspec (dllimport) int subtract (int A, int B );

Tell the compiler that this function is a function in the dynamic link library, which can improve efficiency.

 

4. When writing a DLL, declare the function in dll1.h and include this header file in dlltest. H. In addition, replace _ declspec (dllimport) with a set of macros)

Dll1.h

# Ifdef dll.pdf API

# Else

# Define dllsort API extern "C" _ declspec (dllimport)

# Endifdll1_api int _ stdcall add (int A, int B );

Dllbench API int _ stdcall subtract (int A, int B );

Dll1.cpp code:

# Define dll1_api extern "C" _ declspec (dllexport)

# Include "dll1.h"

# Include <windows. h>

# Include <stdio. h> int _ stdcall add (int A, int B)

{

Return A + B;

} Int _ stdcall subtract (int A, int B)

{

Return A-B;

}

 

5. Add the class point to dll1. It has a function output (int
A, intb), which outputs x and y values on the screen. It must contain the header files windows. h and stdio. H. Then add a button in dlltest to test this function! We can use dumpbinto export and import data of dll1.dlland dlltest.exe. Note that only a function of the class can be exported.

 

6. The name of the function we want to export will not be changed. Add the C in the upper case of extern "C! You can, # define
Dll1_api extern "C" _ declspec (dllexport), but it can only export global functions and cannot export class member functions. If the call convention is changed to another method, the function name is also changed. So this method is not good.

 

7. The solution is to use the module definition file.

A. Create a dll2.dll project;

B. Add two functions, add and subtract, in dll2.cpp.

C. Create the dll2.def file in the directory and add it to the project.

D. Add the following code to dll2.def:

Library dll2exports

Add

Subtract

E. After compilation, run dumpbin to check whether the function name has been changed?

F. Test. This time we use the Dynamic Loading Method to call the DLL file. Previously, we used implicit links. The advantage of dynamic loading is that loading is required, which can improve the execution efficiency. The Code is as follows:

Hinstance hinst;

Hinst = loadlibrary ("dll3.dll ");

Typedef int (/* _ stdcall */* addproc) (int A, int B );

// Addproc add = (addproc) getprocaddress (hinst ,"? Add @ yahhh @ Z ");

Addproc add = (addproc) getprocaddress (hinst, makeintresource (1 ));

If (! Add)

{

MessageBox ("failed to get the function address! ");

Return;

}

Cstring STR;

Str. Format ("5 + 3 = % d", add (5, 3 ));

MessageBox (STR );

Freelibrary (hinst );

 

7. At this time, you change the call convention and the function name will not be changed. But if you add _ stdcall to define the function, you also need to add _ stdcall to the call; otherwise, an error will occur!

 

8. dllmain () is the DLL entry point, but not required. But do not make complicated calls in dllmain. Why? Because some core DLL files may not have been loaded during dllmain loading.

 

9. Create a DLL project based on MFC.

 

10. When no DLL is used, call freelibrary to reduce the DLL usage count, release DLL resources, and reduce the system burden. Understand?

 

11. Summary:

A. *. Def does not change the function name;

B. When it is defined as _ stdcall, _ stdcall must be used for the call.

 

The following code is used:

1. Create a Win32 Dynamic Link Library

2. Create a CPP source file:

int add(int a,int b){return a+b;}int sub(int a,int b){return a-b;}

3vc installation directory ----> vc98 ----> bin ---->
Drag this to run ---> cmd

4

 

5

At this time, no related functions are exported. You need to add keywords to the CPP file.

You can export the function at this time:

It is not exported according to the original name of the function. This may be a specification of VC.

 

Below are several methods to Call DLL files:

1. Create a dialog box-based MFC Program

extern int add(int a,int b);extern int sub(int a,int b);void CDllTestDlg::OnAdd() {// TODO: Add your control notification handler code hereCString cstring;cstring.Format("10086+86=%d",add(10086,86));MessageBox(cstring);}void CDllTestDlg::OnSub() {// TODO: Add your control notification handler code hereCString cstring;cstring.Format("10086-86=%d",sub(10086,86));MessageBox(cstring);}

2. add XX. lib and XX. DLL files to the project directory.

3 # pragma comment (Lib, "lianjieku1.lib ")

You can run it:

 

 

A tool of VC to check who depends on whom:

 

//extern int add(int a,int b);//extern int sub(int a,int b);_declspec(dllimport) int add(int a,int b);_declspec(dllimport) int sub(int a,int b);

Replace the above statement with the following statement, which is more efficient. Other steps are the same as above.

 

 

Register _ declspec (dllimport) int xxxx,

Then add the header file in lianjieku1:

_declspec(dllimport) int add(int a,int b);_declspec(dllimport) int sub(int a,int b);

# Include "../lianjieku1/lianjieku1.h" to import the file.

 

You can also modify the DLL header file and source file

#ifndef DLL_API _declspec(dllimport)#define DLL_API _declspec(dllimport)#endifDLL_API int add(int a,int b);DLL_API int sub(int a,int b);

 

#ifndef DLL_APII _declspec(dllexport)#define DLL_APII _declspec(dllexport)#endif#include"LianJieKu1.h"DLL_APII int add(int a,int b){return a+b;}DLL_APII int sub(int a,int b){return a-b;}

 

You can also introduce the "class" in the DLL"

#ifndef DLL_API _declspec(dllimport)#define DLL_API _declspec(dllimport)#endifDLL_API int add(int a,int b);DLL_API int sub(int a,int b);class DLL_API Point{public:void say(int x,int y);};

You can also export only the member functions,

Class Point

{

Public:

Void dll_api say (int x, int y );

}

#ifndef DLL_APII _declspec(dllexport)#define DLL_APII _declspec(dllexport)#endif#include"LianJieKu1.h"#include<windows.h>#include<stdio.h>DLL_APII int add(int a,int b){return a+b;}DLL_APII int sub(int a,int b){return a-b;}void DLL_APII Point::say(int x,int y){HWND hwnd;hwnd=GetForegroundWindow();HDC hdc=GetDC(hwnd);char ch[20];sprintf(ch,"x=%d,y=%d",x,y);TextOut(hdc,0,0,ch,strlen(ch));ReleaseDC(hwnd,hdc);}

 

void CDllTestDlg::OnPoint() {// TODO: Add your control notification handler code herePoint p;p.say(100,200);}

 

If you want to make a function in the DLL available in C language or other integrated environments, you must add an extern "C", so that the function name remains unchanged during function compilation.

Change both the header file and source file: as shown in Figure

#define DLL1_API extern "C" _declspec(dllimport)

 

#define DLL1_API extern "C" _declspec(dllexport)

The XX. Def file can solve the problem of function name changes during compilation.

Dynamic connection. If you want to call many DLL files, this can save memory.

You do not need to connect to the Lib object or the header file. You only need a DLL file.

int add(int a,int b){return a+b;}int sub(int a,int b){return a-b;}

 

LIBRARY DllTest2EXPORTSaddsub

 

Void ctestdll2dlg: onbutton1 () {// todo: add your control notification handler code herehinstance hinst; hinst = loadlibrary ("dlltest2.dll"); typedef int (* addproc) (int, int B); addproc add = (addproc) getprocaddress (hinst, "add"); If (! Add) {MessageBox ("failed to get function address"); return;} cstring; cstring. format ("5 + 8 = % d", add (5, 8); MessageBox (cstring );}

 

For standard output, typedef int (_ stdcall * addproc) (int A, int B );

 

 

 

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.