写了一个模块(dll),里面的数据结构主要是链表。
另外写了一个测试程序,
void CInference_testDlg::Onengin() 
{
//用来得到调用dll函数的返回结果的
struct result *p;
         UpdateData(true);
m_text.TrimLeft();
char element[100]="";
m_filename.Format("%s","rule.dat");
         p = engine(&m_filename,&m_text,1);  //call function of dll
AfxMessageBox(p->message);
}void CInference_testDlg::OnExit() 
{
OnOK();
}
其实是传递几个参数后调用dll模块。可是每次按退出按钮的时候会报错:   "0x10212923"指令引用的“0x01422750”内存。该内存不能read调试的时候发现如果调用dll函数执行后就会报错,如果不执行就不会报错了。所以我想
错误应该是由于dll函数造成的。但是每次执行dll函数的时候运行都很正常——我指运
行过程中各数据和返回的结果都正确。而且AfxMessageBox(p->message);也都能正常执行。既然如此,我执行函数调用后OnBegin()函数已经执行完了——这个消息被处理完成了,这个时候我在按退出按钮,又怎么会突然冒出来Access Violation问题啊?!如果
真的是我在dll文件里面有wild pointer的话,也不会OnBegin()函数正常执行完啊,而应该是在结果被显示之前就报错了啊!
    请高手指点迷津!

解决方案 »

  1.   

    1。有可能是你的DLL中的函数型别与调用时用的不一样,造成参数入栈顺序不对,如_stdcall与_cdecl
    2.可能你在别处调Freelibrary()
      

  2.   

    为什么会调用dll函数执行的过程和结果都正确,而按退出按钮却会报错——这个时候应该与dll没关系了。如果有关系的话为什么不是在调用dll函数的时候出错呢?
      

  3.   

    可能是你的析构函数中delete了没有存在的对象
      

  4.   

    我释放内存是在dll模块里面完成的,而我的测试程序AfxMessageBox(p->message);也是正确被执行了的,此时内存已经被释放掉了。
    我的测试程序我只写了上面两个函数,执行完Onbegin()函数后我就退出,然后报错。
    我调用dll模块函数的方法不是运行时载入的方法,所以没有使用LoadLibraryEx(),也就没有使用
    FreeLibrary()了。
      

  5.   

    你没有完整的代码,恐怕要想帮你找到原因还真不好办了,你自己可以跟踪一下,跟到DLL中
      

  6.   

    并且调试的时候当我退出时候会弹出一个 Find Source dialog,
    显示 Please enter the path for DBGHEAP.C.
    然后然我选择目录,但是机子上面没有这个文件阿。
      

  7.   

    接上面一条:
        然后我选择cancel候,就指到一条汇编代码了
    --- No source file  --------------------------------------------------------------------------------------------------------
    102128FC   int         3
    102128FD   int         3
    102128FE   int         3
    102128FF   int         3
    --- dbgheap.c  -------------------------------------------------------------------------------------------------------------
    CheckBytes:
    10212900   push        ebp
    10212901   mov         ebp,esp
    10212903   push        ecx
    10212904   push        ebx
    10212905   push        esi
    10212906   push        edi
    10212907   mov         dword ptr [bOkay],1
    1021290E   mov         eax,dword ptr [nSize]
    10212911   mov         ecx,dword ptr [nSize]
    10212914   sub         ecx,1
    10212917   mov         dword ptr [nSize],ecx
    1021291A   test        eax,eax
    1021291C   je          CheckBytes+7Eh (1021297e)
    1021291E   mov         edx,dword ptr [pb]
    10212921   xor         eax,eax10212923   mov         al,byte ptr [edx]   //这便是指向的汇编语句10212925   mov         ecx,dword ptr [bCheck]
    10212928   and         ecx,0FFh
    1021292E   mov         edx,dword ptr [pb]
    10212931   add         edx,1
    10212934   mov         dword ptr [pb],edx
    10212937   cmp         eax,ecx
    10212939   je          CheckBytes+7Ch (1021297c)
    1021293B   mov         eax,dword ptr [bCheck]   看这条汇编语句应该是wild pointer问题,可是如果是调用dll函数的时候出现这种情况的话就应该是在执行函数的时候就报错了,现在却是执行完要退出的时候出问题。
       我不太清楚dll函数调用后程序退出的时候(我调用dll函数采用的不是动态加载的方式)编译器会怎么处理,它应该有一个类似于析构的过程吧,如果这样的话可能是这块地方出错了。请高手指点。
      

  8.   

    p = engine(&m_filename,&m_text,1);  //call function of dll
    m_filename和m_text是什么类型的?CString?如果是,那么可能是不安全的。
    engine是如何定义的?
    engine(const CString& filename, const CString& text, int nResaved = 0);?
    反正我觉得这样是不安全的,我不太清楚CString的引用、拷贝构造等是怎么实现的,看他的源代码好像是通过引用计数实现的。我做过一个程序,也是主程序调用dll并传递CString类型变量,无论怎么传递都出错,但别的类型(int,float等)不会出错(最后是通过先将参数写入注册表然后再在dll中读注册表实现参数传递的。也有可能通过共享数据段实现,但我没试过,不知道行不行)。而当主程序(客户端)用:
    CString str = _T("124");
    mydllinterface(str.GetBuffer(10));调用dll;
    dll(服务器端)用纯C++的string接受参数:
    int mydllinterface(string str);
    则不会出错。
    用int mydllinterface(char* szp);
    也不会错;
    不知以上是否对你有帮助。
      

  9.   

    楼上的大哥说得很有道理,我使用的方法也的确是CString.
    #define DllExport _declspec(dllexport)
    extern "C" DllExport struct result * engine(CString *,CString *,int);    对于CString的不安全我也深有同感,在写程序的过程中我就有一次因为使用了CString::Empty()函数导致其他与之很不相干的数据被破坏了,后来改用其它的方法
    完成才了结。    不过我的数据传递到正常,程序运行也能正常——我做的是推理机,可以得到正确的推理结果。
    就是退出程序的时候会报错。——所以很迷惑。
        
      

  10.   

    p = engine(&m_filename,&m_text,1);  //call function of dll
    返回的p是在dll里面分配的内存吧?那它的释放也应该通过调用dll,
    否则,可能两边使用不同的内存管理模式,出错,详见windows核心编程。
      

  11.   

    可能是要加这一条,这要看你DLL的类型,这条要加在每个DLL导出函数的第一句之前
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
      

  12.   

    我试着加了,不过还是和以前一样。
       keios(嘿嘿)  朋友说得很有道理,我去查看了 《windows核心编程》,里面说到两边使用不同的内存管理模式而出错的问题,我感觉我的程序就可能是犯了这个错误。
              p = engine(&m_filename,&m_text,1);  //call function of dll
              返回的p是指向dll内存的一个链表的指针,如果错误是因为程序退出的时候尝试释放
    p所指向的内存而出错的话,我在程序结束前把p指向NULL.不过还是出错了。不知道为什么?
      

  13.   

    to arbor:
    看你的代码,肯定不是因为释放p的问题,你的程序根本没有释放,也就是说内存泄漏,但不会造成你所说的错误,如果你愿意,我可以帮你找,但你要把代码发到我邮箱里[email protected]
    你可以把机密的部分给删掉
      

  14.   

    我以前碰到过一个类似问题,就是调用dll模块的程序退出的时候出错——但是程序运行结果也是正确的。开始我也一直以为不应该是dll模块中内存引用的问题,不过后来发现却是。所以建议你还是
    到dll函数模块中仔细搜寻一下。
      

  15.   

    非常感谢各位朋友的关系,这个问题我终于解决了。就是dll函数模块中出了wild pointer问题。
    不过很纳闷的是为什么这种问题报错不是在调用dll函数模块的时候报错,却在调用程序结束的时候
    报错。
    再次感谢各位朋友的关心。