dll:
#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif#define DEFINECALLBACK(func) typedef void (__stdcall *func)DEFINECALLBACK(CALLBACKFUNCTION_TEST1)(int n);extern "C"
{
DLLTEST_API void SetCallBack_Test(CALLBACKFUNCTION_TEST1 CallBack);
DLLTEST_API int GetValue(void);
};
CALLBACKFUNCTION_TEST1 fnCallBack = NULL;extern "C" DLLTEST_API void SetCallBack_Test(CALLBACKFUNCTION_TEST1 CallBack)
{
fnCallBack = CallBack;
}extern "C" DLLTEST_API int GetValue(void)
{
return 10;
}client:
#define DEFINECALLBACK(func) typedef void (WINAPI *func)DEFINECALLBACK(CALLBACKFUNCTION_TEST_CLIENT)(int n);void WINAPI funcTestGGG(int n)
{}
void CClientDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
//OnOK();
HINSTANCE hInst = LoadLibrary(_T("dlltest.dll"));
if (NULL != hInst)
{
typedef void (WINAPI* MYCALLBACKFUNCTION)(CALLBACKFUNCTION_TEST_CLIENT callBackFunc);
MYCALLBACKFUNCTION SetCallBack = (MYCALLBACKFUNCTION)::GetProcAddress(hInst, "SetCallBack_Test");
if (NULL != SetCallBack)
{
SetCallBack(funcTestGGG);
} typedef int (WINAPI* GETVALUE)(void);
GETVALUE GetValue = (GETVALUE)::GetProcAddress(hInst, "GetValue");
if (NULL != GetValue)
{
int n = GetValue();
CString strTemp;
strTemp.Format(_T("%d"), n);
AfxMessageBox(strTemp);
}
}
}SetCallBack(funcTestGGG);这句的时候出现弹出对话框,提示信息为: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.请各位大虾赐教。

解决方案 »

  1.   

    用Release版本试试,Debug版本,默认会检查这个ESP,
      

  2.   

    你的DLL的函数调用约定是__stdcall,而你编译器默认的是_cdecl,两者不一致,在Debug模式下,默认会检查,所以会有这个问题...你也可以修改你的exe工程的调用约定为__stdcall
      

  3.   

    realse 版本出现如下错误提示框:
    Client.exe 中的 0x00000001 处未处理的异常: 0xC0000005: 读取位置 0x00000001 时发生访问冲突
      

  4.   

    那你尝试修改一下calling conversion
      

  5.   

    @oyljerry,不知如何修改,请赐教!
      

  6.   

    工程属性 -》 C/C++ -》 Advanced -》 Calling Conversion
      

  7.   

    typedef void (WINAPI* MYCALLBACKFUNCTION)(CALLBACKFUNCTION_TEST_CLIENT callBackFunc);
    其中WINAPI实际上是stdcall的calling conversion,
    而DLLTEST_API void SetCallBack_Test(CALLBACKFUNCTION_TEST1 CallBack);VC中默认是_cdecl,二者不匹配。
    你可以将WINAPI去掉:        typedef void (* MYCALLBACKFUNCTION)(CALLBACKFUNCTION_TEST_CLIENT callBackFunc);
            MYCALLBACKFUNCTION SetCallBack = (MYCALLBACKFUNCTION)::GetProcAddress(hInst, "SetCallBack_Test");
            if (NULL != SetCallBack)
            {
                SetCallBack(funcTestGGG);
            }
      

  8.   

    最好不要该默认的调用约定。
    在OnBnClickedOk中:
    typedef void (WINAPI* MYCALLBACKFUNCTION)(CALLBACKFUNCTION_TEST_CLIENT callBackFunc);
      

  9.   

    如楼上两位所说,去掉WINAPI之后,并没有任何改观,调用约定:dll是__cdecl (/Gd) client是__stdcall (/Gz)
      

  10.   

    呵呵,问题已解决,将client的调用约定改成__cdecl (/Gd) 即可。
    多谢cnzdgs,多谢qgw_2000,多谢oyljerry,多谢多谢。