Udostępnij za pośrednictwem


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.

Zobacz też

Koncepcje

Importowanie do aplikacji