首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

VC++ DLL 跨模塊虛函數調用約定不匹配導致 ESP 錯誤解決

     編輯:程式設計綜合問答

問題現象

接口 DLL 定義虛函數(非純虛),平台 EXE 調用,游戲 DLL 實現。新增虛函數後,部分游戲調用報 Run-Time Check Failure #0 - The value of ESP was not properly saved,提示調用約定不匹配。

根因分析

  • 雖然項目設置均為 __cdecl (/Gd),但 虛函數調用通過 vtable 間接調用,編譯器對虛函數的調用約定處理可能因優化、內聯、不同編譯單元導致不一致。
  • 顯式指定 __stdcall/__cdecl/WINAPI 反而破壞了編譯器默認的 thiscall 約定(MSVC 成員函數默認 thiscall:this 指針通過 ECX 傳遞,調用方清棧)。

解決方案

  1. 不顯式指定調用約定,保持虛函數聲明為 virtual void OnEventABC(int a, bool b);,讓編譯器使用默認 thiscall。
  2. 確保所有模塊使用相同編譯器版本、相同運行時庫(/MD 或 /MT)、相同結構體對齊(/Zp)。
  3. 導出類聲明加 `__declspec(dllexport)` / `__declspec(dllimport)` 宏,確保 vtable 正確導出導入。
  4. 純虛函數接口類:接口類僅含純虛函數,實現類繼承並覆寫,避免「非純虛函數默認實現」引發的二進制兼容問題。

最佳實踐

跨 DLL 多態接口採用 COM 風格:純虛接口 + 工廠函數創建對象,避免直接跨模塊 new/delete 和虛函數默認實現共享。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved