https://msdn.microsoft.com/zh-cn/library/a90k134d.aspx
https://msdn.microsoft.com/zh-cn/library/ms235636.aspx
?
?
可以使用兩種方法將公共符號(hào)導(dǎo)入到應(yīng)用程序中或從 DLL 導(dǎo)出函數(shù):
-
生成 DLL 時(shí)使用模塊定義 (.def) 文件
-
在主應(yīng)用程序的函數(shù)定義中使用關(guān)鍵字 __declspec(dllimport) 或 __declspec(dllexport)
模塊定義 (.def) 文件是包含一個(gè)或多個(gè)描述 DLL 各種特性的 Module 語(yǔ)句的文本文件。 如果不使用 __declspec(dllimport) 或 __declspec(dllexport) 導(dǎo)出 DLL 函數(shù),則 DLL 需要 .def 文件。
可以使用 .def 文件 導(dǎo)入到應(yīng)用程序中 或 從 DLL 導(dǎo)出 。
Visual C++ 用 __declspec(dllimport) 和 __declspec(dllexport) 取代以前在 16 位版的 Visual C++ 中使用的 __export 關(guān)鍵字。
不使用 __declspec(dllimport) 也能正確編譯代碼,但使用它可以使編譯器生成更好的代碼。 編譯器之所以能夠生成更好的代碼,是因?yàn)樗梢源_定函數(shù)是否存在于 DLL 中,這使得編譯器可以生成跳過(guò)間接尋址級(jí)別的代碼,而這些代碼通常會(huì)出現(xiàn)在跨 DLL 邊界的函數(shù)調(diào)用中。 但是,必須使用 __declspec(dllimport) 才能導(dǎo)入 DLL 中使用的變量。
如果有正確的 .def 文件 EXPORTS 節(jié),則不需要 __declspec(dllexport) 。 添加 __declspec(dllexport) 是為了提供不使用 .def 文件從 .exe 或 .dll 文件導(dǎo)出函數(shù)的簡(jiǎn)單方法。
Win32 可移植可執(zhí)行文件格式旨在最小化為修改導(dǎo)入而必須訪問(wèn)的頁(yè)數(shù)。 為此,它將所有程序的所有導(dǎo)入地址都放在一個(gè)稱(chēng)為“導(dǎo)入地址表”的位置。 這使得加載程序在訪問(wèn)這些導(dǎo)入時(shí)可以只修改一兩頁(yè)。
?
?
?
?
?
Microsoft 在 Visual C++ 的 16 位編譯器版本中引入了 __export ,使編譯器得以自動(dòng)生成導(dǎo)出名并將它們放到一個(gè) .lib 文件中。 然后,此 .lib 文件就可以像靜態(tài) .lib 那樣用于與 DLL 鏈接。
在更新的編譯器版本中,可以使用 __declspec(dllexport) 關(guān)鍵字從 DLL 導(dǎo)出數(shù)據(jù)、函數(shù)、類(lèi)或類(lèi)成員函數(shù)。 __declspec(dllexport) 會(huì)將導(dǎo)出指令添加到對(duì)象文件中,因此您不需要使用 .def 文件。
當(dāng)嘗試導(dǎo)出 C++ 修飾函數(shù)名時(shí),這種便利最明顯。 由于對(duì)名稱(chēng)修飾沒(méi)有標(biāo)準(zhǔn)規(guī)范,因此導(dǎo)出函數(shù)的名稱(chēng)在不同的編譯器版本中可能有所變化。 如果使用 __declspec(dllexport) ,僅當(dāng)解決任何命名約定更改時(shí)才必須重新編譯 DLL 和依賴(lài) .exe 文件。
許多導(dǎo)出指令(如序號(hào)、NONAME 和 PRIVATE)只能在 .def 文件中創(chuàng)建,并且必須使用 .def 文件來(lái)指定這些特性。 不過(guò),在 .def 文件的基礎(chǔ)上另外使用 __declspec(dllexport) 不會(huì)導(dǎo)致生成錯(cuò)誤。
若要導(dǎo)出函數(shù), __declspec(dllexport) 關(guān)鍵字必須出現(xiàn)在調(diào)用約定關(guān)鍵字的左邊(如果指定了關(guān)鍵字)。 例如:
__declspec(dllexport) void __cdecl Function1(void);
若要導(dǎo)出類(lèi)中的所有公共數(shù)據(jù)成員和成員函數(shù),關(guān)鍵字必須出現(xiàn)在類(lèi)名的左邊,如下所示:
class __declspec(dllexport) CExampleExport : public CObject { ... class definition ... };
![]() |
---|
__declspec(dllexport) 不能應(yīng)用于具有 __clrcall 調(diào)用約定的函數(shù)。 |
生成 DLL 時(shí),通常創(chuàng)建一個(gè)包含正在導(dǎo)出的函數(shù)原型和/或類(lèi)的頭文件,并將 __declspec(dllexport) 添加到頭文件中的聲明中。 若要提高代碼的可讀性,請(qǐng)為 __declspec(dllexport) 定義一個(gè)宏并對(duì)正在導(dǎo)出的每個(gè)符號(hào)使用該宏:
#define DllExport __declspec( dllexport )
__declspec(dllexport) 將函數(shù)名存儲(chǔ)在 DLL 的導(dǎo)出表中。 如果希望優(yōu)化表的大小,請(qǐng)參見(jiàn) 按序號(hào)而不是按名稱(chēng)從 DLL 導(dǎo)出函數(shù) 。
![]() |
---|
將 DLL 源代碼從 Win16 移植到 Win32 時(shí),請(qǐng)用 __declspec(dllexport) 替換 __export 的每個(gè)實(shí)例。 |
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
