为特定的 mfc dll 调用 AfxEnableMemoryLeakDump

Posted

技术标签:

【中文标题】为特定的 mfc dll 调用 AfxEnableMemoryLeakDump【英文标题】:Calling AfxEnableMemoryLeakDump for a specific mfc dll 【发布时间】:2012-07-10 11:47:03 【问题描述】:

我们有一个 Visual Studio Unicode 应用程序,我们在其中使用了一些外部 dll。在这个应用程序中加载了 mfc100ud.dll(注意 u,它代表 Unicode)。该应用程序还使用了一些与 mfc100d.dll 链接的外部 dll(因此没有 Unicode)。

在我们的应用程序中,我想通过调用 AfxEnableMemoryLeakDump(FALSE) 来禁用作为 Afx 一部分的内存泄漏转储。当我调用这个函数时,我最终进入了 mfc100ud.dll,因为我们直接与这个 dll 链接。然而,稍后外部 dll 被加载,因此 mfc100d.dll 也被加载。 当应用程序关闭时,mfc100d.dll 被卸载,由于没有为此 dll 调用 AfxEnableMemoryLeakDump,我们的 MemoryLeakDump 仍然发生。

为了解决这个问题,我尝试通过这样做显式调用 dll 中的函数:

  PGNSI pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("mfc100d.dll")),
       "?AfxEnableMemoryLeakDump@@YGHH@Z"); // 64-bit
  if (pGNSI!=nullptr)
  
    pGNSI(FALSE);
  
  pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("mfc100d.dll")),
       "?AfxEnableMemoryLeakDump@@YAHH@Z"); // 32-bit
  if (pGNSI!=nullptr)
  
    pGNSI(FALSE);
  

我使用 dumpbin.exe 来查找修饰的函数名称。

但这不起作用,因为 GetProcAddress 为 32 位和 64 位返回一个 nullptr。 有人可以帮忙吗?

【问题讨论】:

【参考方案1】:

AfxenableMemoryLeakDump 不是按名称导出,而是按其序数值导出。您可以通过dumpbin 显示的[NONAME] 标记来判断这一点。这是我得到的:

C:\Windows\System32>dumpbin /exports mfc100d.dll | grep AfxEnableMemoryLeakDump
      15902      003A20D0 [NONAME] ?AfxEnableMemoryLeakDump@@YGHH@Z (int __stdcall AfxEnableMemoryLeakDump(int))

第一个值15902 是序数值。 GetProcAddress 文档说明:

lpProcName [in] 函数或变量名,或函数的序数值。如果该参数为序数值,则必须在低位字中;高位字必须为零。

所以试试

const WORD AfxEnableMemoryLeakDumpOrdinal = 15902;
GetProcAddress( GetModuleHandle( ... ), (LPCSTR)AfxEnableMemoryLeakDumpOrdinal );

【讨论】:

以上是关于为特定的 mfc dll 调用 AfxEnableMemoryLeakDump的主要内容,如果未能解决你的问题,请参考以下文章

2015.3.4 VS2005调用MFC dll时报错及解决

MFC如何调用DLL(VC++)

MFC:Win32-Dll及MFC-Dll编写调用

为啥从属性页调用afxmessagebox到扩展dll时mfc死锁

从 DLL 调用函数时 MFC 断言错误

从 MFC 调用 ATL COM dll