MFC-DLL示例介绍

    技术2022-05-19  23

    MFC应用向导可以生成MFC支持的两种DLL:扩展DLL和常规DLL。下面将介绍这两种DLL的区别:

    扩展DLL支持C++接口,换句话说该DLL可以导出整个类,客户可以构造这些类的对象或从这些类进行派生。扩展DLL动态链接到MFC库中的DLL版本中的代码(所以扩展DLL文件比较小),因此,扩展DLL要求库户程序也必须能够动态链接到MFC库(MFC应用程序向导的默认设置),所以扩展DLL只能应用到MFC应用程序中。

    常规dLL可以被任何Win32编程环境装载,它的限制就是常规DLL只能导出C风格的函数,而不能导出C++类、成员函数或重载函数,不过在常规DLL中是可以使用C++类(特别是MFC库的类)。当生成常规DLL时,可以选择静态链接或动态链接到MFC库。如果选择了静态链接DLL将包含所有它需要的MFC库代码的拷贝,因此它是自包含的,当然了这样生成的DLL文件会比较大。如果选择动态链接,则文件会相对小些,但是必须保证在目标机器上存在适当的MFC DLL。

    1.扩展DLL源码示例

    1.1创建扩展DLL

    启动VC6,使用MFC DLL向导创建初始扩展DLL项目;

    在此工程中新建了一对话框资源其对应的类文件为MyDlg.h、MyDlg.cpp

    //MyDlg.h源码

    class AFX_EXT_CLASS CMyDlg : public CDialog//因要到处此类所以需在类名前添加AFX_EXT_CLASS宏 {

        ......};

       ......

    编译运行便可生成.lib和.dll文件

    1.2DLL调用

    将导出DLL对应类的头文件拷贝到客户应用程序目录下并加载到应用程序中,lib和dll文件拷贝到项目的debug目录下;

    装入.lib文件:(1)project->Setting...->Link 设置.lib文件所在全路径;(2)#pragma comment(lib, “debug/NewClassDll.lib")  

    #include "MyDlg.h"

    ......

    void CTemp222Dlg::OnButton1() { CMyDlg dlg; dlg.DoModal();}

    2.常规DLL示例

    2.1DLL创建

    启动VC6 使用MFC DLL向导创建初始动态链接DLL项目;

    向.cpp文件中添加如下函数代码:

    extern "c" __declspec(dllexport) double MyFun(double d)

    {

     AFX_MANAGE_STATE(AfxGetStaticModuleState())

    //当调用的MFC动态链接库mfc70.dll作为进程的一部分被装入时,它把数据存放在一些实际的全局变量中。如果是从MFC程序或DLL中调用MFC函数,则mfc70.dll会知道如何代表调用进程去设置这些全局变量。然而从一个常规MFCDLL 中调用进入mfc70.dll,则这些全局变量并不同步,其结果不可知为了解决这个问题,需在每个导出函数开始处添加此行代码。

     ......

    }

     编译运行便可生成.lib和.dll文件

    2.2DLL调用

    还是以隐式调用为例装入lib库的方式与上面讲的方法一样;

    声明导入函数用于查找DLL加载后在内存中预存的到处函数的地址,示例代码:

    extern "c" _declspec(dllimport) double MyFun(double d);

    关键源码:

    #pragma comment(lib, “debug/NewClassDll.lib") 

    extern "c" _declspec(dllimport) double MyFun(double d);

    ......

    m_dOutput=MyFun(20);

    ......

    3.关于DLL中使用的资源

    当一个程序包含了扩展DLL和常规DLL中都且其都使用了资源,资源搜索序列为:首先是EXE文件,然后是扩展DLL;如果是DLL装入一个资源,则搜索序列为:首先是扩展DLL,然后是MFC DLL,最后是EXE。

    如果需要的话可以修改资源搜索序列,假如希望EXE代码首先搜索DLL的资源,则可以使用如下代码:HINSTANCE hInstResourceClient=AfxGetResourceHandle();

    //Use DLL's instanse handel

    AfxSetResourceHandel(::GetMoudleHandle("mydllname.dll"));

    CString strRes;

    strRes.LoadString(IDS_MYSTRING)//获取DLL中标示为IDS_MYSTRING字符串资源

    //Restore Client's instanse handle

    AfxSetResourceHandel(hInstResourceClient);


    最新回复(0)