你描述的是Regular DLL Dynamically Linked to MFC。从这篇链接的文章中选择部分描述为您提供了一组特征:
动态链接到 MFC 的常规 DLL 具有以下内容
要求:
这些 DLL 是使用定义的 _AFXDLL 编译的,就像动态链接到 MFC DLL 的可执行文件一样。但是 _USRDLL 是
也定义了,就像静态链接到的常规 DLL
MFC。
这种类型的 DLL 必须实例化一个 CWinApp 派生类。
这种类型的 DLL 使用 MFC 提供的 DllMain。将所有特定于 DLL 的初始化代码放在 InitInstance 成员函数中
和 ExitInstance 中的终止代码,就像在普通 MFC 应用程序中一样。
如果您使用 VS2010 中的 New Project Wizatd 并选择创建 MFC DLL 的选项,这是您获得的默认设置,尽管您可以从向导选项中选择其他类型的 DLL:
所以,创建一个常规 DLL。它将为您生成必要的样板代码,包括CWinApp 派生类。例如:
// CMFCLibrary1App
BEGIN_MESSAGE_MAP(CMFCLibrary1App, CWinApp)
END_MESSAGE_MAP()
// CMFCLibrary1App construction
CMFCLibrary1App::CMFCLibrary1App()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CMFCLibrary1App object
CMFCLibrary1App theApp;
// CMFCLibrary1App initialization
BOOL CMFCLibrary1App::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
我建议您创建这样一个项目,然后将现有代码移植到其中,然后您将从一开始就拥有所有正确的项目设置和结构。这比尝试转换要容易得多,例如一个 exe 项目到一个 dll 项目。
请务必注意编写导出函数的方式不同。正如上面的链接所说:
因为这种DLL使用的是MFC的动态链接库版本,
您必须将当前模块状态显式设置为
动态链接库。为此,请在开头使用 AFX_MANAGE_STATE 宏
从 DLL 导出的每个函数。
所以即使你只导出 C 风格的函数,如果它们包装使用 MFC 的对象,那么导出的函数和导出类的任何公共函数都必须使用上述技术,尤其是对于多线程应用程序。
新项目模板也有助于插入 cmets 来解释这一点:
//TODO: If this DLL is dynamically linked against the MFC DLLs,
// any functions exported from this DLL which call into
// MFC must have the AFX_MANAGE_STATE macro added at the
// very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
上述cmets中提到的技术注释有:
看到您使用LoadLibrary 来动态加载您的DLL,如果您是从MFC 应用程序执行此操作,您最好使用AfxLoadLibrary(以及相应的AfxFreeLibrary)。正如 MSDN 所说:
对于加载扩展 DLL 的 MFC 应用程序,我们建议您
使用 AfxLoadLibrary 而不是 LoadLibrary。 AfxLoadLibrary 句柄
在调用 LoadLibrary 之前进行线程同步。界面
(函数原型)到 AfxLoadLibrary 与 LoadLibrary 相同。
documentation for AfxLoadLibrary 有更多详细信息。