Twoje wyniki importu są powiązane z funkcją, która jest nazywana czasem ładowania lub niejawnym łączeniem. To plik wykonywalny zawiera metadane, które nakazują programowi ładującemu system operacyjny załadowanie biblioteki DLL, a następnie powiązanie z nazwanymi funkcjami. Jeśli ten proces łączenia w czasie ładowania zakończy się niepowodzeniem, nie można załadować pliku wykonywalnego.
Masz kilka opcji, aby uniknąć łączenia w czasie ładowania, a tym samym pozwolić programowi być odpornym na łączenie awarii.
Delay-loading DLL
Dodaj dyrektywę delayed
do importu funkcji. Dokumentacja mówi:
Aby opóźnić załadowanie biblioteki zawierającej funkcję moment funkcja jest rzeczywiście potrzebne, dołącz opóźnioną dyrektywę do funkcji importowanej:
function ExternalMethod(const SomeString: PChar): Integer; stdcall;
external 'cstyle.dll' delayed;
opóźnione, zapewnia biblioteka, która zawiera zaimportowaną funkcję , nie jest ładowana podczas uruchamiania aplikacji, ale raczej po pierwszym wywołaniu funkcji dla tej funkcji.
Dokumentacja zawiera innych przydatnych tematów, które wykraczają w sposób bardziej szczegółowy, a pokrycie sposobu obsługi błędów:
Explicit załadunek i wiążących się z DLL
Dyrektywa delayed
jest jedynie zwięzłym sposobem, aby kompilator zaaranżował jawne ładowanie biblioteki DLL. Możesz zrobić to samo ręcznie korzystając z LoadLibrary
i GetProcAddress
.
- Zadzwoń pod
LoadLibrary
, aby załadować bibliotekę DLL. Podaj pełną ścieżkę do biblioteki DLL lub po prostu jej nazwę. W tym drugim przypadku polegasz na poleceniu wyszukiwania DLL, aby zlokalizować bibliotekę DLL. Połączenie z LoadLibrary
daje uchwyt modułu.
- Zadzwoń pod
GetProcAddress
, aby uzyskać adres wskazanego wskaźnika funkcji. Musisz dostarczyć uchwyt modułu od kroku 1.
- Wywołanie wskaźnika funkcji zwróciło się z kroku 2.
- Gdy nie trzeba już wywoływać funkcji, należy użyć
FreeLibrary
, aby usunąć bibliotekę DLL.
Na każdym kroku należy sprawdzić zwracane wartości funkcji w przypadku błędu. Sposób obsługi błędów jest udokumentowany dla każdej funkcji Win32 API w dokumentacji MSDN (w związku z powyższym). Na przykład, jeśli nie można znaleźć biblioteki DLL, wówczas LoadLibrary
zwraca 0
. Musisz to wykryć i odpowiednio poradzić sobie z konsekwencjami.
Dyskusja
Chociaż dyrektywa delayed
jest bardzo wygodne, ja osobiście nigdy nie używane. Z mojego doświadczenia wynika, że ilekroć musiałem się wyraźnie połączyć, zawsze stwierdziłem, że potrzebuję dodatkowej elastyczności, której nie oferuje delayed
. Być może moje potrzeby są szczególne, ale nie zdziw się, jeśli znajdziesz się w kierunku wyraźnych połączeń z numerami LoadLibrary
i GetProcAddress
.
Jako przykład, właśnie dzisiaj znalazłem się za pomocą LoadLibraryEx
, ponieważ chciałem przekazać flagę LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
. Tego rodzaju drobnoziarnista kontrola nie jest dostępna, gdy używasz delayed
.
Użyj funkcji LoadLibrary i uzyskaj adres procedury. –