调试: 解决跨进程时使用CString报错的问题, [Invalid Address specified to RtlFreeHeap]

    技术2022-06-23  34

    起因:

      今天我封了一个类, 里面有CFileDialog的操作. 作为工程内的实现运行时,完全正常.

      为了其他MFC程序代码重用, 制作了带导出类的MFC扩展DLL. 当在另外一个exe中调用此Dll时, IDE在跨进程CString串赋值的时候报错.

     

      找了下资料, 没有说道要害处的文章. 经过实验, 发现这是mfc的一个BUG. 我的解决方法是, 如果跨进程对CString赋值操作, 需要另外写一个专门的跨进程CString赋值的函数. 变形后的CString跨进程使用如下, 经过实验, 下面的代码运行稳定正常.

    void ProcessStringCopy(CString & strProcessInside, CString & strProcessOutside) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); /** * 跨进程使用CString时, 第一次操作进程外的CString变量是正常的. * 第二次操作进程外的CString变量时, 如果新的串长度 > 第一次的串长度 * 就会报错, "Invalid Address specified to RtlFreeHeap" * 这应该是CString的一个BUG, 下面的改版用法是正确的 */ int nLen = strProcessOutside.GetLength() + 1; LPTSTR pBufProcessInside = strProcessInside.GetBuffer(nLen); strcpy(pBufProcessInside, strProcessOutside); strProcessInside.ReleaseBuffer(); } int fnTestLsFileDialog() { CLsFileDialog Dlg; CString csPathNameProcessInside; csPathNameProcessInside = "*.exe"; Dlg.SetDefaultExt(csPathNameProcessInside); csPathNameProcessInside = "*.exe"; Dlg.SetDefaultFileName(csPathNameProcessInside); csPathNameProcessInside = "EXE文件 (*.exe)|*.exe|DLL文件 (*.dll)|*.dll|OCX文件 (*.ocx)|*.ocx|RAR文件 (*.rar)|*.rar|PDF文件 (*.pdf)|*.pdf||"; Dlg.SetFileTypeFilter(csPathNameProcessInside); csPathNameProcessInside = "c://windows//"; Dlg.SetInitialPath(csPathNameProcessInside); Dlg.SetOpenType(TRUE); csPathNameProcessInside = "请选择存在的可执行类型文件"; Dlg.SetTitle(csPathNameProcessInside); //打开一个现有文件 if(IDOK == Dlg.UsrDoModal()) { ProcessStringCopy(csPathNameProcessInside, Dlg.m_pfileDlg->GetPathName()); printf("pathname to load = [%s]/n", csPathNameProcessInside); } //让用户选择一个要保存的全路径文件名 Dlg.SetOpenType(FALSE); csPathNameProcessInside = "请选择要保存的可执行类型文件"; Dlg.SetTitle(csPathNameProcessInside); if(IDOK == Dlg.UsrDoModal()) { ProcessStringCopy(csPathNameProcessInside, Dlg.m_pfileDlg->GetPathName()); printf("pathname to save = [%s]/n", csPathNameProcessInside); } /** * 运行结果 * pathname to load = [C:/WINDOWS/twunk_16.exe] * pathname to save = [C:/WINDOWS/twunk_32.exe] */ return S_OK; }

     

    用这种方法来解决[跨进程使用CString报错], 较为简单方便~, 在网上还没看到用这种方法解决问题的思路~.

     

    为了给客户调用时写的Dll, 传递的应该都是标准的Win32内建类型, 要不调用方也没办法使用.

     

    为了给同种语言调用, 可以传递非标的参数.

    对于C++调用, Dll中导出类是一个好的选择.

     

    对于MFC程序, 导出MFC类, 使用起来更方便. 如果客户要实现同样的功能, 在此MFC导出类Dll上再封个标准的Dll给他. 这样做,工作量比较小.

     

     


    最新回复(0)