共用方式為


使用 匯入函式呼叫 __declspec(dllimport)

使用 __declspec(dllimport) 標注呼叫可以加快呼叫速度。 __declspec(dllimport) 一律需要存取匯出的 DLL 資料。

從 DLL 匯入函式

下列程式碼範例示範如何使用 將 __declspec(dllimport) DLL 的函式呼叫匯入應用程式。 func1假設 是 DLL 中的函式,與包含 main 函式的 可執行檔不同。

如果沒有 __declspec(dllimport) ,請指定下列程式碼:

int main(void)
{
   func1();
}

編譯器會產生如下所示的程式碼:

call func1

而連結器會將呼叫轉譯成類似以下的內容:

call 0x4000000         ; The address of 'func1'.

如果 func1 存在於另一個 DLL 中,則連結器無法直接解析此位址,因為它無法知道的位址 func1 為何。 在 32 位和 64 位環境中,連結器會在已知的位址產生 Thunk。 在 32 位的環境中,Thunk 看起來像:

0x40000000:    jmp DWORD PTR __imp_func1

以下是 __imp_func1 可執行檔匯入位址表中位置的位址 func1 。 連結器知道所有這些位址。 載入器只需要在載入時更新可執行檔的匯入位址資料表,才能正常運作。

這就是為什麼使用 __declspec(dllimport) 更好:因為連結器在不需要時不會產生 Thunk。 Thunks 會使程式碼變大(在 RISC 系統上,它可以是數個指示),而且可能會降低快取效能。 如果您告訴編譯器函式位於 DLL 中,它可以為您產生間接呼叫。

因此,現在此程式碼:

__declspec(dllimport) void func1(void);
int main(void)
{
   func1();
}

會產生此指示:

call DWORD PTR __imp_func1

沒有 Thunk,也沒有 jmp 指示,因此程式碼會更小、更快。 您也可以使用整個程式優化來 __declspec(dllimport) 取得相同的效果。 如需詳細資訊,請參閱 /GL (整個程式最佳化)

針對 DLL 內的函式呼叫,您不需要使用間接呼叫。 連結器已經知道函式的位址。 在間接呼叫之前,載入和儲存函式的位址需要額外的時間和空間。 直接呼叫一律會更快且更小。 您只想要在從 DLL 本身外部呼叫 DLL 函式時使用 __declspec(dllimport) 。 建置該 DLL 時,請勿 __declspec(dllimport) 在 DLL 內的函式上使用 。

另請參閱

匯入至應用程式