Importowanie wywołania funkcji jako __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 wygląda następująco:
call func1
i program łączący tłumaczy wywołanie na coś takiego:
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 żadnego sposobu dowiedzenia jaki adres func1 jest.W środowiskach 16-bitowy program łączący dodaje adres ten kod do listy w pliku .exe, który moduł ładujący poprawka czy w czasie wykonywania z poprawnym adresem.W środowiskach 32-bitowe i 64-bitowych program łączący generuje thunk, których znasz adres.W środowisku 32-bitowe pośredniczącej wygląda:
0x40000000: jmp DWORD PTR __imp_func1
W tym miejscu imp_func1 jest adresem dla func1 gniazdo w tabeli Adres importu pliku .exe.Wszystkie adresy wiadomo, więc program łączący.Moduł ładujący ma tylko zaktualizować tabele adresów importu pliku .exe w czasie ładowania wszystko działało poprawnie.
W związku z tym, za pomocą __declspec(dllimport) jest lepsze, ponieważ program łączący nie generuje thunk, jeśli nie jest wymagane.Thunks powiększyć kod (w systemach RISC, może być kilka instrukcji) i może zmniejszyć wydajność pamięci podręcznej.Jeśli kompilator jest powiedzieć, że funkcja jest w bibliotece DLL, go wygenerować pośredniego wywołania dla Ciebie.
Teraz ten kod:
__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}
generuje instrukcję:
call DWORD PTR __imp_func1
Nie ma żadnych thunk i nr jmp instrukcji, więc kod jest mniejsze i szybciej.
Z drugiej strony dla wywołań funkcji wewnątrz biblioteki DLL, chcesz użyć pośredniego wywołanie.Znasz już adresu funkcji.Ponieważ czas i miejsce są wymagane ładować i przechowywać adres funkcji przed pośredniego wywołanie, bezpośrednie wywołanie jest zawsze mniejsze i szybciej.Chcesz użyć __declspec(dllimport) podczas wywoływania funkcji DLL poza sama biblioteka DLL.Nie należy używać __declspec(dllimport) funkcji wewnątrz biblioteki DLL podczas budowania tej biblioteki DLL.