DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
如果使用VC编写DLL时,需要MFC功能; 一般在源文件里就不能手动写DLLMAIN函数了

它给MFC集成了,\src\mfc\dllmodule.cpp
打开它,里面有有一个DLLMAIN函数,根据源码意思就可以看出来,

这里截取的一点点代码
if (dwReason == DLL_PROCESS_ATTACH)
    {
        BOOL bResult = FALSE;

#ifdef _AFXDLL
        // wire up resources from core DLL
        AfxCoreInitModule();
#endif

        _AFX_THREAD_STATE* pState = AfxGetThreadState();
        AFX_MODULE_STATE* pPrevModState = pState->m_pPrevModuleState;

        // Initialize DLL's instance(/module) not the app's
        if (!AfxWinInit(hInstance, NULL, _T(""), 0))
        {
            AfxWinTerm();
            goto Cleanup;       // Init Failed
        }

        // initialize the single instance DLL
        CWinApp* pApp; pApp = AfxGetApp();////关键在这里了
        if (pApp != NULL && !pApp->InitInstance())///这里会调用 初始化函数
        {
            pApp->ExitInstance();///这也是退出时函数
            AfxWinTerm();
            goto Cleanup;       // Init Failed
        }

        pState->m_pPrevModuleState = pPrevModState;
#ifdef _AFXDLL
        // wire up this DLL into the resource chain
        VERIFY(AfxInitExtensionModule(controlDLL, hInstance));
        TRY
        {
            CDynLinkLibrary* pDLL; 
            pDLL = new CDynLinkLibrary(controlDLL);
        }
        CATCH(CMemoryException, e)
        {
            DELETE_EXCEPTION(e);
            pApp->ExitInstance();
            AfxWinTerm();
            goto Cleanup;       // Init Failed
        }
        END_CATCH



DLL_PROCESS_ATTACH

DLL_PROCESS_DETACH

这是莪们关心的,从上面代码中可以看到,这里面MFC调用一个全局的CWinApp类的 初始化函数


也就是说,现在写一个类,让它继承CWinApp

然后重载它的InitInstace 和ExitInstace就可以了

在InitInstace时里面写入所需要的代码就可以了

然后在声明一个全局的变量,一定要是个全局变量

当然这个类可以不用做任何事情,就提供初始化和退出时处理的函数



如果在DLL 动态库中导出全局变量
extern int __decspec


如果EXE中要使用DLL中的资源,因为DLL和EXE的资源ID很有可能会冲突,在函数第一行加入如下代码可解决此问题

AFX_MANAGE_STATE(AfxGetStaticModuleState());

AFX_MANAGE_STATE是一个宏,其原型为: 

AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )


该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指向栈上对象的作用域),先前的模块状态将由AFX_MODULE_STATE的析构函数恢复。

方法二 在DLL接口函数中使用:

AfxGetResourceHandle();

AfxSetResourceHandle(HINSTANCE xxx);


AfxGetResourceHandle用于获取当前资源模块句柄,而AfxSetResourceHandle则用于设置程序目前要使用的资源模块句柄。

我们将DLL中的接口函数ShowDlg改为:
void ShowDlg(void)

{ 

//方法2的状态变更

HINSTANCE save_hInstance = AfxGetResourceHandle(); 

AfxSetResourceHandle(theApp.m_hInstance); 



CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框

dlg.DoModal();

//方法2的状态还原

AfxSetResourceHandle(save_hInstance);
posted on   DoubleLi  阅读(1899)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2011-12-31 [C#/ASP.NET]List<>中Sort()、Find()、FindAll()、Exist()的使用方法
2011-12-31 Delegate,Action,Func,Predicate的使用与区别
2011-12-31 C# 参考:令人惊喜的泛型委托 Predicate/Func/Action
2011-12-31 C#委托与Lambda表达式
点击右上角即可分享
微信分享提示