__stdcall約定
如果通過VC++編寫的DLL欲被其他語言編寫的程式調用,應將函數的調用方式聲明為__stdcall方式,WINAPI都採用這種方式,而C/C++預設的調用方式卻為__cdecl。__stdcall方式與__cdecl對函數名最終產生符號的方式不同。若採用C編譯方式(在C++中需將函式宣告為extern "C"),__stdcall呼叫慣例在輸出函數名前面加底線,後面加“@”符號和參數的位元組數,形如_functionname@number;而__cdecl呼叫慣例僅在輸出函數名前面加底線,形如_functionname。
Windows編程中常見的幾種函數型別宣告宏都是與__stdcall和__cdecl有關的(節選自windef.h):
#define CALLBACK __stdcall //這就是傳說中的回呼函數
#define WINAPI __stdcall //這就是傳說中的WINAPI
#define WINAPIV __cdecl
#define APIENTRY WINAPI //DllMain的入口就在這裡
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
在lib.h中,應這樣聲明add函數:
int __stdcall add(int x, int y);
在應用工程中函數指標類型應定義為:
typedef int(__stdcall *lpAddFun)(int, int);
若在lib.h中將函式宣告為__stdcall調用,而應用工程中仍使用typedef int (* lpAddFun)(int,int),運行時將發生錯誤(因為類型不符,在應用工程中仍然是預設的__cdecl調用),彈出7所示的對話方塊。
圖7 呼叫慣例不匹配時的運行錯誤
圖8中的那段話實際上已經給出了錯誤的原因,即“This is usually a result of …”。
http://pcedu.pconline.com.cn/empolder/gj/vc/0509/699672_6.html