Run-Time Check Failure #0,The value of ESP was not properly saved 錯誤解決


調用DLL函數,出現錯誤

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.

錯誤原因:

你定義函數指針原型時出錯。

其實你定義的沒有錯,但是編譯器不認識而已,因為你調用的dll函數是一個遠函數,而且是一個C函數,你得告訴編譯器它是個c函數才行。那么你就可以在定義該函數的時候加上一句話,

FAR PASCAL 或者 __stdcall 這個就OK了。

具體做法:

比如說你要定義一個 返回類型為空,參數為空的函數指針:

typedef void (*LPFUN)(void);

這樣確實跟我們dll里的函數匹配了,上面也說了,我們應該添上幾個字,告訴編譯器這個是一個遠的C函數。

typedef void (WINAPI *LPFUN)(void);

typedef void (__stdcall *LPFUN)(void);

typedef void (FAR PASCAL *LPFUN) (void);

像上面這樣定義就OK了,如果用的是VC++,那么直接用第一種定義就ok了。

注意,上面是使用 MFC (DLL)的做法。

如果是WIN32 DLL,得相應的去掉WINAPI ,__stdcall ,FAR PASCAL 這幾個參數。因為WIN32 DLL 默認的入棧方式為 __cedcall方式,不是__stdcall方式。

具體的組合方式太多了,反正知道錯誤的原因是聲明相應的函數未匹配就行了。

調用DLL里的函數 或 類成員函數 碰到此錯誤:

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.

函數定義的調用規則,和實際的調用規則不同。如 編譯器默認的是__cdecl,而__stdcall 類型的函數卻用了 __cdecl 的調用規則,由於編譯時不會報錯,結果出現了運行時異常。

所以把在函數定義中進行設置調用規則即可解決此問題。

如: typedef void (__stdcall Foo)(int a);

很久沒寫代碼,一天幾行的代碼:

typedef int ( *PFUN)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
void CTestProcessMonitorDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here

//MessageBox(TEXT("Hello"), TEXT("Test"));

//typedef void (*pfv) ();

HMODULE hmod = ::LoadLibraryExW(TEXT("user32.dll"), NULL, 0);
if (hmod != NULL)
{
    PFUN pFun= (PFUN)GetProcAddress(hmod, "MessageBoxW");
    if (pFun != NULL)
    {
        pFun(m_hWnd, TEXT("Hello"), TEXT("Test"), MB_YESNO);
    }

   :FreeLibrary(hmod);
}

}

突然出現以下的錯誤:

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.

代碼改為如下, 則問題沒有了

typedef int (WINAPI *PFUN)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
void CTestProcessMonitorDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here

//MessageBox(TEXT("Hello"), TEXT("Test"));

//typedef void (*pfv) ();

HMODULE hmod = ::LoadLibraryExW(TEXT("user32.dll"), NULL, 0);
if (hmod != NULL)
{
    PFUN pFun= (PFUN)GetProcAddress(hmod, "MessageBoxW");
    if (pFun != NULL)
    {
        pFun(m_hWnd, TEXT("Hello"), TEXT("Test"), MB_YESNO);
    }

     ::FreeLibrary(hmod);
}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM