c語言編譯的動態連接庫中,導出的符號名字就是 源代碼中的相應的名字;linux
例如函數 void test(){} 導出的符號名字 就是 testc++
可是對於c++ 來說不是這樣, c++ 有類, 名字空間, 函數重載, 致使多個不一樣的對象可能使用一個相同的名字, 這樣必須由編譯器來生成全局的惟一名字;
windows
這種生成的方式 沒有標準化, 因此 window上的vc 編譯器可能生成一種名字, linux上的gcc 可能生成一種名字, mingw 可能也會生成一種名字;函數
所以不一樣編譯器生成的C++動態庫, 從符號名字上來說,不兼容。指針
可是若是須要從C++庫導出某些名字 使得你們都認識該怎麼作呢?對象
源代碼中寫下:
編譯器
extern "c"{編譯
void test();
test
}
import
將會生成 標準的c符號名字, 也就是 test, 這樣全部人都會認識這個符號了!
固然要注意一點 全部聲明該符號的位置 不能出如今名字空間中, 不然 仍舊生成 C++類型的符號名字。
標準c中定義了函數的參數的壓棧和出棧相關問題: 壓棧從右向左壓入參數;而當函數返回的時候, 由調用者負責清理堆棧, 彈出 相應的參數
也就是被調用者 直接return, 調用者再清理 堆棧頂部指針, 這樣實現printf 函數就比較方便了(可變長度參數, 被調用者不用關心參數的數量)
可是win32中, 有一種windows專用的stdcall方法, 參數也是從右向左壓入, 可是 函數返回的時候是由被調用者清理堆棧
也就是被調用者先拿到返回地址, 在設置堆棧頂部指針, 最後返回(被調用者須要關心參數的數量)
這些是windows 須要的東西:
所以在寫win32程序的時候 若是須要 採用標準的 c參數處理方式, 就須要顯示的告訴 編譯器;
__cdecl 標準c的參數管理方式 __stdcall windows的參數管理方式
主要用於dll說明參數的管理方式的:
__declspec(dllexport)用於導出 該動態庫 的標準c方式的函數
__declspec(dllimport) 用於一個動態庫 依賴於 另外一個動態庫的函數