Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Importowanie wywołań funkcji przy użyciu polecenia
Dodawanie adnotacji do wywołań za pomocą elementu __declspec(dllimport) może przyspieszyć ich działanie.
__declspec(dllimport) jest zawsze wymagany do uzyskania dostępu do wyeksportowanych danych DLL.
Importowanie funkcji z biblioteki DLL
Poniższy przykład kodu przedstawia sposób importowania __declspec(dllimport) wywołań funkcji z biblioteki DLL do aplikacji. Załóżmy, że func1 jest to funkcja, która znajduje się w bibliotece DLL niezależnie od pliku wykonywalnego zawierającego funkcję main .
Bez __declspec(dllimport)polecenia podanego w tym kodzie:
int main(void)
{
func1();
}
kompilator generuje kod, który wygląda następująco:
call func1
a konsolidator tłumaczy wywołanie na coś takiego:
call 0x4000000 ; The address of 'func1'.
Jeśli func1 istnieje w innej biblioteki DLL, konsolidator nie może rozpoznać tego adresu bezpośrednio, ponieważ nie ma możliwości poznania, jaki jest adres func1 . W środowiskach 32-bitowych i 64-bitowych konsolidator generuje thunk pod znanym adresem. W środowisku 32-bitowym thunk wygląda następująco:
0x40000000: jmp DWORD PTR __imp_func1
Oto __imp_func1 adres func1 miejsca w tabeli adresów importu pliku wykonywalnego. Wszystkie te adresy są znane konsolidatorowi. Moduł ładujący musi zaktualizować tylko tabelę adresów importu pliku wykonywalnego w czasie ładowania, aby wszystko działało poprawnie.
Dlatego użycie __declspec(dllimport) jest lepsze: ponieważ konsolidator nie generuje thunk, jeśli nie jest wymagany. Thunks sprawiają, że kod jest większy (w systemach RISC, może to być kilka instrukcji) i może obniżyć wydajność pamięci podręcznej. Jeśli informujesz kompilator, że funkcja znajduje się w bibliotece DLL, może wygenerować wywołanie pośrednie.
Teraz ten kod:
__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}
generuje następującą instrukcję:
call DWORD PTR __imp_func1
Nie ma tunk i nie ma jmp instrukcji, więc kod jest mniejszy i szybszy. Możesz również uzyskać ten sam efekt bez __declspec(dllimport) użycia całej optymalizacji programu. Aby uzyskać więcej informacji, zobacz /GL (Optymalizacja całego programu).
W przypadku wywołań funkcji w bibliotece DLL nie chcesz używać wywołania pośredniego. Konsolidator zna już adres funkcji. Ładowanie i przechowywanie adresu funkcji przed wywołaniem pośrednim zajmuje trochę czasu i miejsca. Bezpośrednie wywołanie jest zawsze szybsze i mniejsze. Chcesz użyć __declspec(dllimport) tylko podczas wywoływania funkcji DLL spoza samej biblioteki DLL. Nie używaj __declspec(dllimport) funkcji wewnątrz biblioteki DLL podczas kompilowania tej biblioteki DLL.