说明:
DLL(VC6,MBCS编码)
调用者EXE(VC6,MBCS)DLL中的方法
void test(CStringArray &arr)
{
  arr.Add(_T("hello"));
}在exe工程中调用
CStringArray arr ;
**.test(arr);调试状态下出现下述错误:

解决方案 »

  1.   

    看不到图。
    使用MFC静态库会不会出错?
      

  2.   

    你的编译选项是mdd还是mtd,全都改成mdd
      

  3.   

    另外看看Release版是否报错。Debug中有一些安全检查,模块之间传递数据有时会被认为不安全而报错。
      

  4.   


    VC6的EXE调用该DLL情况:
      Release版DLL+Release版EXE   不报错。
      Release版DLL+DEBUG版EXE     报错。   Debug版DLL+ Release版EXE  报错
      Debug版DLL+DEBUG版EXE      不报错 VC7,8的EXE调用该DLL情况:
        Debug版DLL+DEBUG版EXE(MBCS)      报错 
         Debug版DLL+DEBUG版EXE(UNICODE)      报错
        Debug版DLL+ Release版EXE(UNICODE)  报错/************VC8错误信息***********************************
    HEAP[test.exe]: Invalid Address specified to RtlFreeHeap( 003A0000, 00383140 )
    Windows 已在 test.exe 中触发一个断点。其原因可能是堆被损坏,这也说明 test.exe 中或它所加载的任何 DLL 中有 bug。
    ************************************************/另:
    刚刚搜到一个贴子,是和我一样的问题请大家看看他们的讨论过程,也许结合各位的经验,能找到解决办法,谢谢http://topic.csdn.net/t/20040324/13/2880110.html
      
      

  5.   


    请问在哪里改呢?别外mdd,mdt是什么?
      

  6.   


    我所说的结果正确是
    CString ss = arr.GetAt(0); 
    的结果正确,程序还是要中断的
      

  7.   

    传递引用的时候加上const
    一般来说dll接口不能使用类相关的.很容易引起莫名其妙的问题.
      

  8.   

    LZ测试的还真够全面。
    只要EXE与DLL都用Release时不报错,并且程序运行正常,就说明代码是没问题的,只是被认作“不安全”,可以不用管它。如果要解决这个问题,就只能换方法了,不用CStringArray&参数。
      

  9.   

    别用CStringArray作为参数,出错是因为想delete其它模块分配的内存,两个模块都在操作内存,不错才怪。举个简单的例子:
    EXE创建了变量CStringArray str;
    EXE增加了数据,例如str.Add(),此时在EXE中分配了缓冲区
    EXE把str作为引用传递给DLL
    DLL再次增加数据,例如str.Add(),此时当预留缓冲区不够时引发自动的内存重分配,realloc调用尝试释放一段内存并重新分配更大的内存,但是原有内存是在EXE模块中分配的,在DLL中删除一个不存在的内存句柄肯定会引发错误。事实上,CStringArray中的很多函数都会导致内存重分配,这些函数不能跨模块调用。
    还是换一种类型作为参数吧。
      

  10.   

    mdd和mtd是编译选项,分别表示多线程调试dll和多线程调试,如果你的程序使用了dll,就一定要使用mdd
      

  11.   

    参照http://topic.csdn.net/t/20060821/15/4964582.html所述方法,解决了VC6工程的调用问,但是VC7,8都无法通过
    /////
    流的方式如下:   
      void   CDriveTestDlg::OnBnClickedOk()   
      {   
      CStringArray   dd;   
        
      dd.Add(_T("dsadfdsa"));//   
        
      IOutAdo::GetAllProductList(dd);     
        
      dd.Add(_T("dsadfdsa"));//   
      }   
        
      DLL程序:   
      bool   IOutAdo::GetAllProductList(CStringArray&   ProductList)   
      {   
      CStringArray   strArray;   
      strArray.Add(_T("test"));   
      strArray.Add(_T("test"));   
      CMemFile   CacheFile;   
      CArchive   ar((CFile   *)&CacheFile,   CArchive::store);   
      strArray.Serialize(ar);   
      ar.Close();   
      //文件指针重置   
      CacheFile.SeekToBegin();   
        
      CArchive   ar1((CFile*)&CacheFile,   CArchive::load);   
      ProductList.Serialize(ar1);   
      ar1.Close();   
      return   TRUE;   
      }   ///
    本人初学,不知道怎么才能使其通用于6,7,8的环境现准备换Vector试试了,不知道成不成
      

  12.   


    用vector应该也有同样的问题...请问可用什么类型的参数代替呢?
      

  13.   

    正解,这还包括STL的所有类。
    总的原则就一个,谁分配的就由谁来释放。
      

  14.   

    不要用MFC的方法和STL,虽然STL的可行的,但是需要特别的导出声明。用COM的数据类型:VARIANT, SAFEARRAY等等
      

  15.   


    对头,COM设计的优点之一就是统一使用完全独立的COM堆来分配内存,所以不存在跨模块管理内存的问题。COM内存的分配和释放本质上全部是由IMalloc接口完成的,像SysAllocString就是专门用来分配BSTR的,SAFEARRAY也必须由SafeArrayCreate之类的专用API来管理内存,其他方式分配的内存都是不合法的。这样做能保证COM组件适用于任何模块,也适用于任何语言。当然,使用COM数据类型不是唯一的选择。有些封装类(比如CString)可以使用自定义的内存管理器,你只要实现内存管理器接口并从全局堆中统一管理内存,也能跨模块传递。