Jak pozbyć się problemów z „brakującą biblioteką DLL”?

15

Zrobiłem kilka gier za pomocą Visual C ++ 2015 i OpenGL. Kiedy uruchomiłem go na moim komputerze, nie było problemu, ale kiedy uruchomiłem go na innych komputerach, pokazuje, że brakuje niektórych bibliotek DLL. Chcę wiedzieć, jak się upewnić, że nie powtórzy się to następnym razem, i co powinienem wziąć pod uwagę, aby uniknąć problemów z brakiem plików?

Ankit singh kushwah
źródło
8
Najpierw upewnij się, że budujesz wersję Release.
user253751
3
Jeśli chcesz mieć absolutną pewność, że nie ma żadnych zależności od samego VS - ale ma to swoją własną wadę - w ustawieniach generowania kodu możesz wybrać wielowątkowe / wielowątkowe debugowanie (dla kompilacji debugowania) zamiast MT DLL / DLL debugowania MT . Zwiększa rozmiar pliku wykonywalnego, a skompilowane w ten sposób pliki binarne nie skorzystają z aktualizacji bibliotek DLL środowiska wykonawczego. Ale to zależy od ciebie. Plusem jest to, że twój plik wykonywalny nie będzie miał zależności „zewnętrznych”. Nie opublikuję tego jako odpowiedzi, ponieważ nie jest to rozwiązanie twojego problemu, tylko obejście.
Gizmo,
@Gizmo obejście jest nadal odpowiedzią, a komentarze są tymczasowe i służą do wyjaśnienia zawartych w nich postów i mogą zostać usunięte. Więc jeśli jest to przydatne, powinieneś opublikować je jako odpowiedź.
user1306322,
Hm, w porządku. Prześlę go wtedy jako odpowiedź.
Gizmo,

Odpowiedzi:

22

Musisz zainstalować składniki redystrybucyjne dla wersji programu Visual Studio używanego na dowolnym komputerze, który chce uruchomić pliki wykonywalne, np. Https://www.microsoft.com/en-us/download/details.aspx?id=48145 dla VS2015 . Możesz także potrzebować redystów dla DirectX lub innych komponentów.

Instalatorzy aplikacji zazwyczaj instalują wszystkie składniki redystrybucyjne dla dowolnej z ich zależności. Możesz utworzyć taki instalator za pomocą InnoSetup, NSIS, WIX lub różnych innych narzędzi.

Możliwe jest tworzenie plików wykonywalnych, które nie wymagają żadnych składników redystrybucyjnych, ale jesteś ograniczony do podzbioru podstawowych funkcji systemu Windows, co zasadniczo nie wystarcza, aby stworzyć jakąkolwiek sensowną grę lub dużą aplikację. Same instalatory są przykładem aplikacji, które nie wymagają żadnych zależności do uruchomienia.

Sean Middleditch
źródło
Czy można użyć VS do zbudowania takiego instalatora? Myślałem, że raz widziałem coś o nazwie OneClick w ustawieniach projektu.
user1306322,
@ user1306322: absolutnie jedno rozwiązanie zostało wspomniane w komentarzach do pytania Gizmo. To tylko kwestia, z którymi środowiskami uruchomieniowymi / bibliotekami DLL łączysz. W ustawieniach domyślnych łączysz się z biblioteką CRT DLL specyficzną dla wersji, ale można to zmienić, chowając opcje linkera. Wystarczy połączyć z MSVCRT.DLL(dołączony do samego systemu Windows) zamiast MSVCPxxx.DLL(wersje specyficzne dla wersji zawarte w wydaniach Visual Studio).
Sean Middleditch,
Lub jeśli masz na myśli zbudowanie kompletnego instalatora, to w zasadzie taki jest WIX . To typowy, zbyt skomplikowany bzdury Microsoft, ale to działa. Były też „projekty instalacyjne”, choć uważam, że zniknęły od 2013 lub 2015 r.
Sean Middleditch,
7

Używam Dependency Walker do śledzenia brakujących bibliotek DLL:

Dependency Walker jest również bardzo przydatny do rozwiązywania problemów z błędami systemowymi związanymi z ładowaniem i wykonywaniem modułów. Zależność Walker wykrywa wiele typowych problemów z aplikacjami, takich jak brakujące moduły, nieprawidłowe moduły, niedopasowania importu / eksportu, błędy zależności cyklicznej, niedopasowane typy modułów maszyn i niepowodzenia inicjalizacji modułów.


Istnieje również opcja czasu kompilacji w VS do statycznego łączenia bibliotek DLL:

  • Łączenie statyczne oznacza, że ​​biblioteki DLL są zawarte w pliku EXE.
  • Łączenie statyczne zwiększa rozmiar pliku EXE.
  • Łączenie statyczne oznacza, że ​​ta wersja biblioteki DLL będzie zawsze używana.
  • Łączenie statyczne oznacza jednak, że nigdy nie będziesz mieć problemu z brakującymi bibliotekami DLL.
Leftium
źródło
1
Walker zależności jest dość stary. Nie poprawnie emuluje już mechanizmy Windows do ładowania bibliotek DLL. Często prowadzi do fałszywych komunikatów o niemożności znalezienia bibliotek DLL.
jpmc26
Linkowanie statyczne może być zabronione w licencji zależności.
KeyWeeUsr
6

W przypadku Visual C ++ masz kilka możliwości obsługi redystrybucji: uruchom EXE z instalatora (z uprawnieniami administratora), użyj modułu scalającego MSM z instalatorem MSI, a nawet bibliotek DLL. Szczegóły w MSDN .

Większy problem to OpenGL. Jedyną wersją OpenGL, która jest dołączona do systemu Windows, jest renderer oprogramowania OpenGL 1.5. Cokolwiek innego wymaga zainstalowania zewnętrznego urządzenia ICD.

Jest to jeden z powodów, dla których tak wiele gier Windows używa DirectX, ponieważ jest on dołączony do systemu operacyjnego. Zobacz Wdrażanie Direct3D 11 dla twórców gier i Nie taka bezpośrednia konfiguracja .

Chuck Walbourn
źródło
1
Porada OpenGL jest nieaktualna - każdy nowoczesny sterownik karty graficznej jest wyposażony w aktualny OpenGL ICD.
user253751
Osobiście musiałem instalować biblioteki DLL OpenGL na maszynach w wieku zaledwie jednego roku
Gnemlock
@Gnemlock Natychmiast po ponownej instalacji systemu Windows na wspomnianym rocznym komputerze możesz mieć rację. Czy ten problem nadal występował po zainstalowaniu oficjalnego pakietu sterowników firmy NVIDIA, AMD lub Intel?
Damian Yerrick
2
@Gnemlock - jeśli ręcznie instalujesz biblioteki DLL OpenGL, robisz coś strasznie złego. Jeśli naprawdę masz na myśli „zainstaluj sterownik dostawcy GPU”, to właśnie to powiedział immibis.
Maximus Minimus,
@Gnemlock - ach, więc nie dotyczy to wtedy prawdziwego świata. Dzięki za wyjaśnienie.
Maximus Minimus
1

Zastrzeżenie: Jest to obejście , nie rozwiązanie twojej odpowiedzi, ale bardzo realna możliwość.

Jeśli chcesz mieć absolutną pewność, że nie ma żadnych zależności od samego VS - ale ma to swoje wady - w ustawieniach generowania kodu możesz wybrać opcję Multi Threaded (MT) / Multi Threaded Debug (MD) (dla kompilacji debugowania ) zamiast MT DLL (MTd) / MT Debug DLL (MDd).

enter image description here

Jakie są wady?

  • Zwiększa rozmiar pliku wykonywalnego i plik binarny (chociaż przy tworzeniu gry jest to prawdopodobnie nieistotne)
  • skompilowane w ten sposób nie skorzystają z aktualizacji bibliotek DLL środowiska uruchomieniowego. (np. jeśli Microsoft wyda VC ++ 2015 SP2, SP3, SP4 itp.) Ale to zależy od Ciebie.
  • Większe użycie pamięci RAM (również nieistotne), ponieważ nie używasz ponownie istniejącego / załadowanego kodu (DLL)
  • Musisz upewnić się, że wszystkie biblioteki, które łączysz, są skompilowane z tym samym środowiskiem wykonawczym, w przeciwnym razie połączenie może się nie powieść lub mogą wystąpić interesujące błędy w czasie wykonywania (prawdopodobnie nie, ale zdarzało mi się to raz w życiu w starszym projekcie, który został zaktualizowany do najnowszy VS)

A jakie są zalety?

  • twój plik wykonywalny nie będzie miał „zewnętrznych” zależności od samego VS (bez wymagania msvc * .dll).
  • niektóre osoby postrzegają to jako wzrost wydajności, ponieważ eliminuje się narzut wywołania DLL, podczas gdy jest to teoretycznie prawda, ulepszenia są znikome w praktyce

Sprawdź ten link, aby uzyskać bardziej szczegółowe wyjaśnienie oraz pułapki i problemy, które możesz napotkać przy użyciu statycznego środowiska uruchomieniowego.

Innym obejściem byłoby umieszczenie wszystkich wymaganych bibliotek DLL tam, gdzie jest twój plik binarny. Twoja aplikacja nie skorzysta z aktualizacji (bibliotek wykonawczych), ale to wszystko.

Prawdziwym rozwiązaniem jest dystrybucja aplikacji w trybie dll wydania / braku debugowania (MTd) i dostarczenie poprawnego redystrybucyjnego instalatora VC ++ (oraz wszelkich innych instalatorów bibliotek, których możesz użyć, np. OpenAL, DirectX9, PhysX) i umożliwienie użytkownikowi uruchomienia tego przed uruchomieniem aplikacji (jak wskazały inne odpowiedzi).

Upewnij się również, że użytkownik wie, że może zaktualizować sterowniki GPU (ponieważ zawierają one wiele środowisk wykonawczych dla wielu aplikacji, np. OpenGL, Vulcan).

Gizmo
źródło
0

Moim rozwiązaniem było skopiowanie i wklejenie biblioteki DLL, która spowodowała błąd, do folderu, w którym znajduje się plik .sln w Visual Studio. Po #includesekcji napisałem #pragma comment (lib, "lost DLL name with .dll")i rozwiązałem!

Uwaga: Rozwiązałem problem z biblioteką DLL innej firmy (vulkan api). Może nie wiadomo, ale 90% zadziała, powodzenia :)

użytkownik96759
źródło