Import volání funkcí pomocí __declspec(dllimport)
Anotace volání pomocí nich __declspec(dllimport)
může zrychlit. __declspec(dllimport)
pro přístup k exportovaným datům knihovny DLL se vždy vyžaduje.
Import funkce z knihovny DLL
Následující příklad kódu ukazuje, jak použít __declspec(dllimport)
k importu volání funkcí z knihovny DLL do aplikace. Předpokládejme, že func1
je to funkce, která je v knihovně DLL odděleně od spustitelného souboru, který obsahuje hlavní funkci.
Bez __declspec(dllimport)
tohoto kódu:
int main(void)
{
func1();
}
kompilátor generuje kód, který vypadá takto:
call func1
a linker přeloží volání na něco podobného:
call 0x4000000 ; The address of 'func1'.
Pokud func1
existuje v jiné knihovně DLL, linker nemůže tuto adresu přeložit přímo, protože nemá žádný způsob, jak zjistit, co je adresa func1
. V 32bitových a 64bitových prostředích linker vygeneruje nářez na známé adrese. V 32bitovém prostředí vypadá thunk takto:
0x40000000: jmp DWORD PTR __imp_func1
Tady __imp_func1
je adresa slotu func1
v tabulce adres importu spustitelného souboru. Všechny tyto adresy jsou známé linkeru. Zavaděč musí aktualizovat tabulku adres importu spustitelného souboru pouze v době načtení, aby všechno fungovalo správně.
Proto je použití __declspec(dllimport)
lepší: protože linker nevygeneruje teč, pokud se nevyžaduje. Thunks zvětší kód (v systémech RISC, může to být několik pokynů) a může snížit výkon mezipaměti. Pokud kompilátoru řeknete, že je funkce v knihovně DLL, může za vás vygenerovat nepřímé volání.
Teď tedy tento kód:
__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}
vygeneruje tuto instrukci:
call DWORD PTR __imp_func1
Neexistuje žádný blok dat a žádné jmp
instrukce, takže kód je menší a rychlejší. Stejný účinek můžete získat i bez __declspec(dllimport)
použití optimalizace celého programu. Další informace najdete v tématu /GL (Optimalizace celého programu).<
U volání funkcí v rámci knihovny DLL nechcete používat nepřímé volání. Linker už zná adresu funkce. Načtení a uložení adresy funkce před nepřímým voláním trvá více času a místa. Přímé volání je vždy rychlejší a menší. Chcete použít __declspec(dllimport)
pouze při volání funkcí knihovny DLL mimo samotnou knihovnu DLL. Při sestavování této knihovny DLL nepoužívejte __declspec(dllimport)
funkce v knihovně DLL.