VS2015用C++創(chuàng)建動態(tài)庫DLL步驟如下: (1)啟動VS2015》文件》新建》項(xiàng)目,按下圖進(jìn)行選擇填寫,選擇Win32控制臺應(yīng)用程序或Win32項(xiàng)目都可以,這兩相都會彈出相同的創(chuàng)建窗口,如第二張圖,第三張圖。
(2)在Win32應(yīng)用程序向?qū)υ捒蛑羞x擇【下一步】
(3)按下圖進(jìn)行勾選 預(yù)編譯頭作用:VS 默認(rèn)情況下會創(chuàng)建并使用預(yù)編譯頭文件(也就是自動創(chuàng)建 StdAfx.h 和 StdAfx.cpp 這兩個文件),以便在編譯時加快編譯速度,預(yù)編譯器將它編譯后,會生成一 個 Pre-compiled header ,也就是 pch 文件,這樣下次就可以直接使用這里已經(jīng)編譯好了的代碼了。
(4)整個測試項(xiàng)目創(chuàng)建后,整體效果如下圖:
(5)在解決方案中找到【頭文件】然后右擊選擇【添加】》【新建項(xiàng)】,在彈出的添加新項(xiàng)對話框中進(jìn)行如下選擇:
(6)打開DLLTest.cpp并添加如下圖紅色框中的函數(shù)test1和test2,同時將DLLTest.h頭文件包含進(jìn)來,具體如下圖:
(7)打開DLLTest.h并添加函數(shù)test1和test2的導(dǎo)出形式,具體如下圖:
注意:__stdcall定義導(dǎo)出函數(shù)入口點(diǎn)調(diào)用約定為_stdcall extern "C"說明導(dǎo)出函數(shù)使用C編譯器,則函數(shù)名遵循C編譯器的函數(shù)名修飾規(guī)則,不加extern "C"說明使用C++編譯器的函數(shù)名修飾 規(guī)則,兩種規(guī)則區(qū)別如下:
(1)C編譯器的函數(shù)名修飾規(guī)則
對于__stdcall調(diào)用約定,編譯器和鏈接器會在輸出函數(shù)名前加上一個下劃線前綴,函數(shù)名后面加上一個“@”符號和其參數(shù)的字節(jié)數(shù),例如 _functionname@number。__cdecl調(diào)用約定僅在輸出函數(shù)名前加上一個下劃線前綴,例如_functionname。__fastcall調(diào)用約定在輸出函
數(shù)名前加上一個“@”符號,后面也是一個“@”符號和其參數(shù)的字節(jié)數(shù),例如@functionname@number (2)C++編譯器的函數(shù)名修飾規(guī)則 C++的函數(shù)名修飾規(guī)則有些復(fù)雜,但是信息更充分,通過分析修飾名不僅能夠知道函數(shù)的調(diào)用方式,返回值類型,甚至參數(shù)個數(shù)、參數(shù)類 型。不管__cdecl,__fastcall還是__stdcall調(diào)用方式,函數(shù)修飾都是以一個“?”開始,后面緊跟函數(shù)的名字,再后面是參數(shù)表的開始標(biāo)識 和按照參數(shù)類型代號拼出的參數(shù)表。對于__stdcall方式,參數(shù)表的開始標(biāo)識是“@@YG”,對于__cdecl方式則是“@@YA”,對于 __fastcall方式則是“@@YI”。參數(shù)的具體含義見上篇博客【VS2015用C++創(chuàng)建的動態(tài)庫導(dǎo)出函數(shù)名亂碼原因分析】。 (8)使用extern "C"導(dǎo)出的函數(shù)名,如圖一,不使用extern "C"導(dǎo)出的函數(shù)名,如圖二。
圖一
圖二 注意在圖二中如果看到的函數(shù)不是圖中所示,請?jiān)诤瘮?shù)名上右擊去掉對【Undecorate C++ Functions】的選擇 (9)針對上面的敘述可以看出無論是添加extern "C"還是不添加,都不是我們想要的函數(shù)名,.h頭文件的作用僅僅能導(dǎo)出動態(tài)庫、明確編譯鏈接方式及確定入口點(diǎn)約定,還一個重要作用是打包給開發(fā)者,使其了解動態(tài)庫導(dǎo)出的函數(shù)及對應(yīng)的的參數(shù),為了確保導(dǎo)出函數(shù)名及入口點(diǎn)函數(shù)不變,此時需添加.def文件,步驟如下: (10)在解決方案中找到【源文件】右擊選擇【添加】》【新建項(xiàng)】,在彈出的添加新項(xiàng)對話框中進(jìn)行如下圖所示選擇:
(11)在DLLTest.def文件中寫入如下代碼:
使用def文件的意義:將編譯器生成的函數(shù)修飾去掉,用更加自然、更加容易理解、更加容易記憶的名字來命名函數(shù),而不是一串人一看就嚇一跳的 修飾名字。 (12)在生成解決方案前先進(jìn)行如下修改,CPU選X86還是X64隨便你啦
(13)請注意一定要是Release模式而不能是Debug模式,否則生成的動態(tài)庫DLL文件有可能還是不能被其他語言調(diào)用,原因現(xiàn)在還不清楚,有知道的朋友請留言,謝謝。為對比可查看Release文件夾和Debug文件夾中生成的動態(tài)庫DLL文件的大小也是不同的。 (14)用def文件導(dǎo)出的動態(tài)庫DLL既可以保證函數(shù)名不變也可以保證動態(tài)庫DLL的入口點(diǎn)函數(shù)名不變,同時在.cpp文件中函數(shù)定義中加入__stdcall就可以實(shí)現(xiàn)導(dǎo)出的DLL被其它語言調(diào)用,此時.h頭文件的作用僅僅打包給開發(fā)者,供其查看導(dǎo)出的函數(shù)名及相應(yīng)參數(shù)而已。 |
|