Using mfc in a shared dll как подключить

Обновлено: 07.07.2024

There are actually four different versions of the executable you might build. As well as choosing between the Debug and the Release build, you can either bind the *.lib version of the MFC code into your executable, or you can have your executable look for the *.dll version of the MFC code run time.

To control this, open View | Solution Explorer and make sure the Pop project is highlighted. Then select View | Property Pages. | General . [In Version 6.0, simply select Project | Settings. | General. ] And then you can edit the Use of MFC field to be Use MFC in a Static Library or Use MFC in a Shared DLL . The DLL option is the Visual Studio default.

If you look at the Pop project settings, you'll notice that we've chosen to build the Release version with the static library option and the Debug version with the shared DLL option. What do these decisions mean, and why are they reasonable?

When you are using MFC, a lot of the code used by the program lives in external libraries. In Windows a library can have one of two forms, a *.lib file or a *.dll file. Code from a *.lib file gets linked into your executable, which makes your executable bigger ? about 1 Meg bigger in the case of an MFC program. Code from a *.dll file is left out of your executable, and when the executable starts up, it looks on the host computer's hard drive for a copy of the *.dll file it needs, and loads this code into RAM at that time.

The Link project settings dialog in Visual Studio, Version 6.0

The General project settings dialog in Visual Studio, Version 6.0

If you have an MFC program that expects to find the MFC code in a DLL, when it tries to start up, it will be looking for a file with a name like MFC40.DLL or MFC42D.DLL or maybe MFC42.DLL . Now, Microsoft regularly changes the particular version of the MFC. DLL distributed with Windows, so there is a very good chance that when you move your executable from your Windows machine to somebody else's Windows machine, your executable is not going to find the *.dll file it needs, and instead of running it's going to show the user a cryptic error message. And even if you give the user a copy of the missing *.dll file, you'll usually find that then there's yet another missing *.dll file that your program needs. And so on. Trying to distribute all the necessary *.dll is in fact too complicated to be practical.

It would seem, therefore, that you'd always want to use the MFC in a static library. But, as we already mentioned, using the static library makes the *.exe bigger. As an illustration, Table 20.1 shows the comparative sizes of the four different builds on the June 21, 2001, version of Pop code.

This note describes regular MFC DLLs, which allow you to use the MFC library as part of a Windows dynamic-link library (DLL). It assumes that you are familiar with Windows DLLs and how to build them. For information about MFC extension DLLs, with which you can create extensions to the MFC library, see DLL Version of MFC.

DLL Interfaces

regular MFC DLLs assume interfaces between the application and the DLL are specified in C-like functions or explicitly exported classes. MFC class interfaces cannot be exported.

If both a DLL and an application want to use MFC, both have a choice to either use the shared version of the MFC libraries or to statically link to a copy of the libraries. The application and DLL may both use one of the standard versions of the MFC library.

regular MFC DLLs have several advantages:

The application that uses the DLL does not have to use MFC and does not have to be a Visual C++ application.

With regular MFC DLLs that statically link to MFC, the size of the DLL depends only on the MFC and C runtime routines that are used and linked.

With regular MFC DLLs that dynamically link to MFC, the savings in memory from using the shared version of MFC can be significant. However, you must distribute the shared DLLs, Mfc<version>.dll and Msvvcrt<version>.dll, with your DLL.

The DLL design is independent of how classes are implemented. Your DLL design exports only to the APIs you want. As a result, if the implementation changes, regular MFC DLLs are still valid.

With regular MFC DLLs that statically link to MFC, if both DLL and application use MFC, there are no problems with the application that wants a different version of MFC than the DLL or vice versa. Because the MFC library is statically linked into each DLL or EXE, there is no question about which version you have.

API Limitations

Some MFC functionality does not apply to the DLL version, either because of technical limitations or because those services are usually provided by the application. With the current version of MFC, the only function that is not applicable is CWinApp::SetDialogBkColor .

Building Your DLL

When compiling regular MFC DLLs that statically link to MFC, the symbols _USRDLL and _WINDLL must be defined. Your DLL code must also be compiled with the following compiler switches:

/D_WINDLL signifies the compilation is for a DLL

/D_USRDLL specifies you are building a regular MFC DLL

You must also define these symbols and use these compiler switches when you compile regular MFC DLLs that dynamically link to MFC. Additionally, the symbol _AFXDLL must be defined and your DLL code must be compiled with:

  • /D_AFXDLL specifies that you are building a regular MFC DLL that dynamically links to MFC

The interfaces (APIs) between the application and the DLL must be explicitly exported. We recommend that you define your interfaces to be low bandwidth, and use only C interfaces if you can. Direct C interfaces are easier to maintain than more complex C++ classes.

Place your APIs in a separate header that can be included by both C and C++ files. See the header ScreenCap.h in the MFC Advanced Concepts sample DLLScreenCap for an example. To export your functions, enter them in the EXPORTS section of your module definition file (.DEF) or include __declspec(dllexport) on your function definitions. Use __declspec(dllimport) to import these functions into the client executable.

You must add the AFX_MANAGE_STATE macro at the beginning of all the exported functions in regular MFC DLLs that dynamically link to MFC. This macro sets the current module state to the one for the DLL. To use this macro, add the following line of code to the beginning of functions exported from the DLL:

WinMain -> DllMain

The MFC library defines the standard Win32 DllMain entry point that initializes your CWinApp derived object as in a typical MFC application. Place all DLL-specific initialization in the InitInstance method as in a typical MFC application.

Note that the CWinApp::Run mechanism does not apply to a DLL, because the application owns the main message pump. If your DLL displays modeless dialogs or has a main frame window of its own, your application's main message pump must call a DLL-exported routine that calls CWinApp::PreTranslateMessage.

See the DLLScreenCap sample for use of this function.

The DllMain function that MFC provides will call the CWinApp::ExitInstance method of your class that is derived from CWinApp before the DLL is unloaded.

Linking Your DLL

With regular MFC DLLs that statically link to MFC, you must link your DLL with Nafxcwd.lib or Nafxcw.lib and with the version of the C runtimes named Libcmt.lib. These libraries are pre-built and may be installed by specifying them when you run Visual C++ setup.

Sample Code

See the MFC Advanced Concepts sample program DLLScreenCap for a complete sample. Several interesting things to note in this sample are as follows:

The compiler flags of the DLL and those of the application are different.

The link lines and .DEF files for the DLL and those for the application are different.

The application that uses the DLL does not have to be in C++.

The interface between the application and the DLL is an API that is usable by C or C++ and is exported with DLLScreenCap.def.

The following example illustrates an API that is defined in a regular MFC DLL that statically links to MFC. In this example, the declaration is enclosed in an extern "C" < >block for C++ users. This has several advantages. First, it makes your DLL APIs usable by non-C++ client applications. Second, it reduces DLL overhead because C++ name mangling will not be applied to the exported name. Lastly, it makes it easier to explicitly add to a .DEF file (for exporting by ordinal) without having to worry about name mangling.

The structures used by the API are not derived from MFC classes and are defined in the API header. This reduces the complexity of the interface between the DLL and the application and makes the DLL usable by C programs.

This note describes regular MFC DLLs, which allow you to use the MFC library as part of a Windows dynamic-link library (DLL). It assumes that you are familiar with Windows DLLs and how to build them. For information about MFC extension DLLs, with which you can create extensions to the MFC library, see DLL Version of MFC.

DLL Interfaces

regular MFC DLLs assume interfaces between the application and the DLL are specified in C-like functions or explicitly exported classes. MFC class interfaces cannot be exported.

If both a DLL and an application want to use MFC, both have a choice to either use the shared version of the MFC libraries or to statically link to a copy of the libraries. The application and DLL may both use one of the standard versions of the MFC library.

regular MFC DLLs have several advantages:

The application that uses the DLL does not have to use MFC and does not have to be a Visual C++ application.

With regular MFC DLLs that statically link to MFC, the size of the DLL depends only on the MFC and C runtime routines that are used and linked.

With regular MFC DLLs that dynamically link to MFC, the savings in memory from using the shared version of MFC can be significant. However, you must distribute the shared DLLs, Mfc<version>.dll and Msvvcrt<version>.dll, with your DLL.

The DLL design is independent of how classes are implemented. Your DLL design exports only to the APIs you want. As a result, if the implementation changes, regular MFC DLLs are still valid.

With regular MFC DLLs that statically link to MFC, if both DLL and application use MFC, there are no problems with the application that wants a different version of MFC than the DLL or vice versa. Because the MFC library is statically linked into each DLL or EXE, there is no question about which version you have.

API Limitations

Some MFC functionality does not apply to the DLL version, either because of technical limitations or because those services are usually provided by the application. With the current version of MFC, the only function that is not applicable is CWinApp::SetDialogBkColor .

Building Your DLL

When compiling regular MFC DLLs that statically link to MFC, the symbols _USRDLL and _WINDLL must be defined. Your DLL code must also be compiled with the following compiler switches:

/D_WINDLL signifies the compilation is for a DLL

/D_USRDLL specifies you are building a regular MFC DLL

You must also define these symbols and use these compiler switches when you compile regular MFC DLLs that dynamically link to MFC. Additionally, the symbol _AFXDLL must be defined and your DLL code must be compiled with:

  • /D_AFXDLL specifies that you are building a regular MFC DLL that dynamically links to MFC

The interfaces (APIs) between the application and the DLL must be explicitly exported. We recommend that you define your interfaces to be low bandwidth, and use only C interfaces if you can. Direct C interfaces are easier to maintain than more complex C++ classes.

Place your APIs in a separate header that can be included by both C and C++ files. See the header ScreenCap.h in the MFC Advanced Concepts sample DLLScreenCap for an example. To export your functions, enter them in the EXPORTS section of your module definition file (.DEF) or include __declspec(dllexport) on your function definitions. Use __declspec(dllimport) to import these functions into the client executable.

You must add the AFX_MANAGE_STATE macro at the beginning of all the exported functions in regular MFC DLLs that dynamically link to MFC. This macro sets the current module state to the one for the DLL. To use this macro, add the following line of code to the beginning of functions exported from the DLL:

WinMain -> DllMain

The MFC library defines the standard Win32 DllMain entry point that initializes your CWinApp derived object as in a typical MFC application. Place all DLL-specific initialization in the InitInstance method as in a typical MFC application.

Note that the CWinApp::Run mechanism does not apply to a DLL, because the application owns the main message pump. If your DLL displays modeless dialogs or has a main frame window of its own, your application's main message pump must call a DLL-exported routine that calls CWinApp::PreTranslateMessage.

See the DLLScreenCap sample for use of this function.

The DllMain function that MFC provides will call the CWinApp::ExitInstance method of your class that is derived from CWinApp before the DLL is unloaded.

Linking Your DLL

With regular MFC DLLs that statically link to MFC, you must link your DLL with Nafxcwd.lib or Nafxcw.lib and with the version of the C runtimes named Libcmt.lib. These libraries are pre-built and may be installed by specifying them when you run Visual C++ setup.

Sample Code

See the MFC Advanced Concepts sample program DLLScreenCap for a complete sample. Several interesting things to note in this sample are as follows:

The compiler flags of the DLL and those of the application are different.

The link lines and .DEF files for the DLL and those for the application are different.

The application that uses the DLL does not have to be in C++.

The interface between the application and the DLL is an API that is usable by C or C++ and is exported with DLLScreenCap.def.

The following example illustrates an API that is defined in a regular MFC DLL that statically links to MFC. In this example, the declaration is enclosed in an extern "C" < >block for C++ users. This has several advantages. First, it makes your DLL APIs usable by non-C++ client applications. Second, it reduces DLL overhead because C++ name mangling will not be applied to the exported name. Lastly, it makes it easier to explicitly add to a .DEF file (for exporting by ordinal) without having to worry about name mangling.

The structures used by the API are not derived from MFC classes and are defined in the API header. This reduces the complexity of the interface between the DLL and the application and makes the DLL usable by C programs.

Creating a simple dialog application Windows of type Dialog Based Application by using MFC ( Microsoft Foundation Classes ) library

Progress

1. Run MS Visual Studio.
2. Calling a project in C++

After loading MS Visual Studio you need to call command

Folder name, where you save the project, you need to set, for example:

MS Visual Studio. C++ - MFC Application. Selecting of application type "MFC Application"

Current settings of project are following:

2. Without databases support.

3. Without support of embedded documents (container, mini-server, full-server and so on).

5. The appearance of the application like MS Visual Studio 2008 .

MS Visual Studio. C++ - MFC Application. Options by default

Fig. 2. Options by default

MS Visual Studio. C++ - MFC Project. Window "Application Type"

Let us explain some of the fields of the window.

Application Type:

For our application, it does not matter what variant of MFC library forming you need to select.

MS Visual Studio. C++ - MFC Application

Fig. 4. Selection of decor of frame of main window of application.

  1. Thick frame – in this case the borders of window are thickened.
  2. Minimize box – button of minimize the window.
  3. Maximize box – button of maximize the window.
  4. System menu – system menu, which is placed in the top-left corner of window.
  5. Minimized – mode, when the window of application is minimized to an icon.
  6. Maximized – mode, when the window of application is set to full screen.

You can set the selection of options at their own discretion.

MS Visual Studio. C++ - MFC Application. Window of settings

Fig. 5. Window of settings

In the window at Figure 5 are different options of settings of application.

Let us explain some of them.

MS Visual Studio. C++ - MFC Application. Request for confirmation of the names of the generated classes

Fig. 6. Request for confirmation of the names of the generated classes

MS Visual Studio. C++ - MFC Project. Application form after executing "App Wizard"

Now you can run the application and analyze it work.

3. Classes, that are created in the application

Class CMFCApplication1App is inherited from CWinApp . This class is the class of application in general.

Class CMFCApplicationDlg is the class of dialog for application.

After creating the application, in Solution Explorer the files of classes are created (Fig. 8).

MS Visual Studio. C++ - MFC Project. Application files in Solution Explorer

Fig. 8. Application files in Solution Explorer

In the above listing between directive

realized preventing of re-use of the same file name headers that can even be placed in different folders.

Next is the declaration of class CMFCApplicationApp , which is inherited from class CWinApp .

Class CWinApp includes most of the functionality, which are needed to application.

Virtual function InitInstance() is overloaded in the class.

means, that is used message map.

In the above listing of greatest interest is the function InitInstance ().

In function InitInstance() the application window is created. Is described the variable dlg of type of application window.

means, that given window of application is the main window of all windows, which can be created in application.

Читайте также: