【状况描述】:一个MFC窗口程序要调用SQL的DLL访问数据库。MFC窗口为多字节环境。SQL的DLL为UNICODE环境。
          我把SQL的DLL看做一个黑盒,在有关字符串的地方做字符串转换。Debug时发现有内存泄露:
{441} client block at 0x0124C560, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $0124C560, 64 bytes long
a CDynLinkLibrary object at $0124C560, 64 bytes long
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {440} normal block at 0x0124C4F8, 42 bytes long.
 Data: <   x            > 0C 00 E5 78 0C 00 00 00 0C 00 00 00 01 00 00 00 
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {439} normal block at 0x0124C490, 42 bytes long.
 Data: <   x            > 0C 00 E5 78 0C 00 00 00 0C 00 00 00 01 00 00 00 
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {438} normal block at 0x0124C428, 42 bytes long.
 Data: <   x            > 0C 00 E5 78 0C 00 00 00 0C 00 00 00 01 00 00 00 
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {437} normal block at 0x0124C3C0, 44 bytes long.
 Data: <   x            > 0C 00 E5 78 0D 00 00 00 0D 00 00 00 01 00 00 00 
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {436} normal block at 0x0124C360, 34 bytes long.
 Data: <   x            > 0C 00 E5 78 08 00 00 00 08 00 00 00 01 00 00 00 
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {435} normal block at 0x0124C308, 28 bytes long.
 Data: <   x            > 0C 00 E5 78 05 00 00 00 05 00 00 00 01 00 00 00 
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {434} normal block at 0x0124C2A8, 30 bytes long.还有一些内存报告未贴,但都类似。查了些资料,说使用多个 MFC dll 报告内存泄漏是因为:http://support.microsoft.com/kb/167929/zh-cn
在同一进程中加载多个版本的 MFC DLL 时,将报告这些内存泄漏。由于 MFC 扩展 (AFXDLL) dll 需要完全相同的 MFC DLL,作为调用应用程序,使用 MFC 的规则 (USRDLL) dll 或 ActiveX 控件 (OCX),使用共享的 MFC 版本时,可以只出现此问题。 最常见的情况下混合 ANSI (MFC4xd.DLL) 和 MFC 的 UNICODE (MFC4xxUd.DLL) 版本在同一进程中。这也会发生时混合使用 MFC42d.DLL 和 MFC40d.DLL。 这些内存泄漏通知是假,并可以被忽略。
为区分内存泄露的真假,可以通过重写 CWinApp::ExitInstance() EXE 和 DLL 中的并将 TRACE() 语句放在它们来完成:   int CTestDllApp::ExitInstance()
   {
      TRACE(_T("ExitInstance() for regular DLL: TESTDLL\n"));      return CWinApp::ExitInstance();
   }【问题】:1.在不更改各自的编码环境时,如何能不报内存泄露?
          2.我没有在SQL的DLL代码里找到int CTestDllApp::ExitInstance()这类的函数。如何区分内存泄露的真假?
          3.不同编码方式互相调用DLL是否有什么风险?
望高手指点,感激不尽!
祝您元旦快乐!

解决方案 »

  1.   

    估计是ANSI和UNICODE在字节长度上的差异造成的越界。
    我只是猜测。
      

  2.   

    UNICODE编码的DLL申请内存空间,然后再自己释放自己,应该都可以释放啊。DLL的编码方式不一定都统一,不知道有没有人碰到过类似的问题。
      

  3.   

    MBCS和UNICODE共存那么长时间,相对应的DLL都很多啊?没有朋友遇到这种情况吗?
      

  4.   

    这种内存泄露是用CString类型作为参数引起的,把CString改成char*搜索“mfc\strcore.cpp(141)”
      

  5.   


    目前只能在DLL里添加字符串转换,希望有更兼容的方法,让不同编码方式的DLL可以方便地共同使用。