Importowanie wywołań funkcji przy użyciu atrybutu __declspec(dllimport)
Poniższy przykład kodu pokazuje, jak używać _declspec(dllimport) do importowania wywołania funkcji z biblioteki DLL do aplikacji.Załóżmy, że func1 jest funkcją, która znajduje się w bibliotece DLL, oddzielnie od pliku .exe, który zawiera główne funkcji.
Bez __declspec(dllimport), biorąc pod uwagę ten kod:
int main(void)
{
func1();
}
Kompilator generuje kod, który wygląda tak:
call func1
i program łączący tłumaczy wywołanie na podobny do następującego:
call 0x4000000 ; The address of 'func1'.
Jeśli func1 istnieje w innej bibliotece DLL, program łączący nie może rozpoznać tym bezpośrednio, ponieważ nie ma sposobu, wiedząc, co adres z func1 jest.W 16-bitowych środowisk linker dodaje kod ten adres do listy w pliku .exe, który obiekt loader czy poprawki w czasie wykonywania z poprawnym adresem.W środowiskach 32-bitowych i 64-bitowych program łączący generuje thunk, którego znany adres.W środowisku 32-bitowym thunk wygląda tak:
0x40000000: jmp DWORD PTR __imp_func1
W tym miejscu imp_func1 to adres do func1 gniazdo w tabeli Adres importu pliku .exe.Tym samym wszystkie adresy są znane linker.Moduł ładujący ma tylko do aktualizowania tabeli adresów importu pliku .exe w momencie obciążenia za wszystko działało poprawnie.
Dlatego też przy pomocy __declspec(dllimport) jest lepszy, ponieważ program łączący nie generuje thunk, jeśli nie jest wymagane.Łącznikami powiększyć kod (w systemach RISC, może być kilka instrukcji) i mogą spowodować obniżenie wydajności pamięci podręcznej.Jeśli nakazuje kompilatorowi, że funkcja jest w bibliotece DLL, to można wygenerować wywołanie pośredniego dla Ciebie.
Więc teraz ten kod:
__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}
generuje instrukcję:
call DWORD PTR __imp_func1
Ma nie thunk i nie jmp instrukcji, więc kod jest mniejsze i szybciej.
Z drugiej strony dla wywołań funkcji wewnątrz biblioteki DLL, nie chcesz trzeba używać pośrednich rozmowy.Znasz już adresu funkcji.Ponieważ czas i miejsce są wymagane ładować i przechowywać adres funkcji przed wywołanie pośrednie, bezpośrednie połączenie jest zawsze mniejsze i szybciej.Chcesz użyć __declspec(dllimport) podczas wywoływania funkcji DLL z zewnątrz DLL sam.Nie należy używać __declspec(dllimport) na temat funkcji wewnątrz DLL podczas tworzenia tej biblioteki DLL.