我在程序中显式链接dll,但是调用完毕后,总是出错,跟踪一看是删除某个对象时出错。
那位大虾解决一下。
代码:
typedef void (*pSnippet) (char* path, string& text, string& query, string& snip);
HINSTANCE hDLL;
pSnippet snippet;
hDLL = LoadLibrary("Dll3.dll");
snippet = (pSnippet)GetProcAddress(hDLL,"Snippet");
char* path = "../config";
string query = m_query.GetBuffer();
m_query.ReleaseBuffer();
string body = mwmi.m_szBody.GetBuffer();
mwmi.m_szBody.ReleaseBuffer();
string snip ;
(*snippet)(path,body,query,snip);
FreeLibrary(hDLL);

解决方案 »

  1.   

    这句似乎有问题 :(*snippet)(path,body,query,snip);
    该为:snippet(path,body,query,snip);
      

  2.   

    snippet(path,body,query,snip);直接调用就可以吧~
      

  3.   

    typedef void (__stdcall *pSnippet)(..)
      

  4.   

    dll我不懂.UPUP
    记得看到c++prime上说函数指针用不用*都一样的。
    所以应该不是(*snippet)(path,body,query,snip)的问题吧
    还记得宏__stdcall好像就是被定义成空的
      

  5.   

    不写 __stdcall 就会使用默认的C++风格,被调用的函数关心堆栈当前情况对调用者传入的参数不作清除,这样堆栈就会发生错位,当然结果会出错。
    __stdcall就不一样了,函数会清除调用者传入的堆栈段,或者用POP退栈,或者用RET N方式。通常你用DEPENDS看到函数名不是abc@xxx的,就是用stdcall,所以要用stdcall
      

  6.   

    按照flyelf的改过之后,执行snippet(path,body,query,snip)的时候报错Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention
      

  7.   

    (*snippet)(path,body,query,snip);
    用(*snippet)应该是没有问题的
    但是
    typedef void (*pSnippet) (char* path, string& text, string& query, string& snip);后面三个参数声明的是string& 而你调用的时候直接是string
    应该改为(*snippet)(path,&body,&query,&snip);
    应该就没有问题了啊
      

  8.   

    呵呵,概念错误
    不好意思,新手上路,请勿见怪
    我想应该是
    string snip ;此处的snip没有赋初值,而引用是要赋初值的
    (*snippet)(path,body,query,snip);
      

  9.   

    我猜是snip析构的时候出错原因可能如下(*snippet)(path,body,query,snip);
    这个调用中有三个参数传的是string的引用所以里面你很可能修改其中一个或多个
    修改的时候string可能会重新分配内存,这时候dll调用的是dll当中的new
    而回过头来,string的释放是要在exe中进行的,掉用的delete是exe中的delete
    所以这样new和delete就不匹配了
    如果真是这样的话,有一个最简单的解决方法
    编译exe和dll的时候,Debug版本使用Multiple Thread DLL Debug Library
    Release版本使用Multiple Thread Library这样new和delete就都是msvcrt.dll里面的new和delete了
    从而使之匹配
      

  10.   

    就是snip析构出错,我把snip说明为全局变量后,则在程序退出时出错,所以判断为析构出错。
      

  11.   

    string是你自己定义的类么?
    还是使用的 #include <string>里面的
      

  12.   

    我没有include<string>,就直接用string声明了变量
      

  13.   

    你把string类的析构函数贴出来 
      

  14.   

    我没有自定义析构函数,也没有显式调用过string的析构函数
      

  15.   

    应该没有错的啊
    是不是在Snippet函数里出错了啊
    Snippet里面都做什么了啊
      

  16.   

    单步调试发现调用dll中的snippet函数时,实参的值没有传给形参,很奇怪。
    下面是dll中的函数定义void Snippet(char* path,string& text  , string& query  , string& snip)
    {
    Snippet4NG* pSnippet = new Snippet4NG();
    pSnippet->Init(path);
    pSnippet->GenerateSnippet(text,query,snip,"<b>","</b>");
    }
      

  17.   

    我已经解决问题了,对dll中的函数进行调用时,不能用string或string&作形参,而只能用string*
    修改程序如下
    Snippet (char* path, string* body, string* query, string* snip )
    所有问题ok
      

  18.   

    不能用string或string&作形参
    好像是常识
    用作形参 string没有初始化
      

  19.   

    在函数调用的时候,直接用函数名就可以了吧,所以在“(*snippet)(path,body,query,snip)”这里,直接写成snippet(path,body,query,snip)应该可以的,我的程序就是这样用的啊,^_^,希望各位笑纳!!!因为我也是刚学这个DLL啊,很多问题还需各位的帮忙解决啊,先谢啦!
      

  20.   

    不可能
    我在DLL中的输出函数是
    LPVOID TranslateStr(CString& pParam)
    {
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    pParam="Love";
    return 0;
    }
    在EXE中调用代码如下
    void C**View::OnDllTest() 
    {
    CDC * pDC=GetDC();
    HINSTANCE hInstance;
    typedef LPVOID(* STR_FUNC)(CString&);//请注意此处的定义
    STR_FUNC  pFunction;
    VERIFY(hInstance=::LoadLibrary ("F:\\Eniac\\Test\\Test2\\DLL\\Debug\\DLL.dll")); VERIFY(pFunction=(STR_FUNC )::GetProcAddress(hInstance,"TranslateStr"));
    CString pString;
    (* pFunction)(pString);//请注意此处的调用
    VERIFY(FreeLibrary(hInstance));
    pDC->TextOut (40,140,pString);
    ReleaseDC(pDC);
    }
    结果可以输出Love
    我试过的,不信楼上的和楼主也可以试一下