Sdílet prostřednictvím


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).</a0>

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.

Viz také

Import do aplikace