将 MFC 类封装到 DLL 中

最近需要开发一个可加载皮肤的控件库,需要从 MFC 中继承若干个类,并封装到 DLL 中。在这一过程中遇到了很多问题,主要是项目的配置,花了很多时间才搞定,现在写下来和大家一起分享。


1.创建一个空的 Win32 DLL 项目,将所有 .h 和 .cpp 文件导入到项目中。


2.在.h文件中,在要导出的类的声明中加入 AFX_EXT_CLASS,如

class AFX_EXT_CLASS CSkinDialog : public CDialog {

    ......

};


‍3.在项目属性的 C/C++ 下的 Preprocessor definitions 中,加入 _AFXEXT,并将 _USEDLL 改成 _AFXDLL。


4.配置DLL以何种方式使用MFC和多线程运行时库。以下是我的测试结果:

‍   Use MFC in a Static Library + Debug Multithreaded DLL  通过
   Use MFC in a Shared DLL + Debug Multithreaded DLL    通过
   Use MFC in a Static Library +Debug Multithreaded           编译错误
   Use MFC in a Shared DLL + Debug Multithreaded            编译错误 
   Use MFC in a Static Library + Mulithreaded DLL                通过
   Use MFC in a Shared DLL + Mulithreaded DLL                  通过
   Use MFC in a Static Library + Multithreaded                       编译错误
   Use MFC in a Shared DLL + Multithreaded                         编译错误

可以看到,凡是多线程运行时库选择为静态连接时都会出错,只能动态连接。建议 Debug 模式使用 Use MFC in a Shared DLL + Debug Multithreaded DLL,Release 模式使用 Use MFC in a Shared DLL + Mulithreaded DLL。

5.创建一个MFC exe项目,‍用来测试这个DLL‍。在主窗口类的.h文件中,包含控件库的.h文件,再连接lib文件,如

   #include "..\\SkinDLL\\skinbutton.h"
   #pragma comment(lib, "..\\SkinDLL\\Debug\\Skin.lib")
   exe 的 MFC 使用方式和多线程运行时库也是需要配置的,以下是我的测试结果:

‍    Use MFC in a Static Library +Debug Multithreaded           连接错误
    Use MFC in a Shared DLL +Debug Multithreaded            通过
    Use MFC in a Static Library +DLL Debug Multithreaded  通过
    Use MFC in a Shared DLL +DLL Debug Multithreaded    编译错误
    Use MFC in a Static Library +Multithreaded DLL               连接错误
    Use MFC in a Shared DLL +Multithreaded DLL                 通过
    Use MFC in a Static Library +Multithreaded                        通过
    Use MFC in a Shared DLL +Multithreaded                          编译错误

6.结论:
   A.dll 的运行时库只能动态连接(因为在dll的工程中使用了‍ _AFXDLL 宏)。
   B.exe 的 MFC 连接方式与运行时库的连接方式必须相同(两个要么都动态连接,要么都静态连接)。

7.补充一点,如果 dll 不想使用 MFC,需要将  Use of MFC 设为  Use of Standard Libraries,并在要导出的类的头文件中,加入  #include 即可。 

你可能感兴趣的:(将 MFC 类封装到 DLL 中)