Mam bibliotekę dll z niezarządzanym kodem API C ++, którego potrzebuję w mojej aplikacji .NET 4.0. Ale przy każdej metodzie, którą próbuję załadować moją bibliotekę dll, pojawia się błąd:
Nie można załadować biblioteki DLL „MyOwn.dll”: nie można znaleźć określonego modułu. (Wyjątek od HRESULT: 0x8007007E)
Przeczytałem i wypróbowałem kilka rozwiązań, które znalazłem w Internecie. Nic nie działa..
Próbowałem użyć następujących metod:
[DllImport("MyOwn.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs((UnmanagedType.I4))]
public static extern Int32 MyProIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Kiedy próbowałem postępować zgodnie z tym artykułem i kiedy uruchamiam ten przykład (z pobranego kodu), działa on bez problemu (używany plik dll znajduje się w folderze bin / debug)
Skopiowałem mój plik dll (wraz ze wszystkimi plikami, od których zależy, do mojego folderu bin).
Próbowałem też tego podejścia, ale otrzymałem ten sam błąd:
[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int MyproIni(string DBname, string DBuser_pass,
string WorkDirectory, ref StringBuilder ErrorMessage);
Jakieś sugestie?
Możesz użyć narzędzia dumpbin, aby znaleźć wymagane zależności DLL:
Dzięki temu dowiesz się, które biblioteki DLL muszą zostać załadowane. Szczególnie zwróć uwagę na plik MSVCR * .dll. Widziałem, że kod błędu pojawia się, gdy nie jest zainstalowany poprawny pakiet redystrybucyjny Visual C ++.
„Pakiety redystrybucyjne Visual C ++ dla programu Visual Studio 2013” można pobrać z witryny internetowej firmy Microsoft. Instaluje c: \ windows \ system32 \ MSVCR120.dll
W nazwie pliku 120 = 12,0 = Visual Studio 2013.
Uważaj, aby mieć odpowiednią wersję programu Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) odpowiednią architekturę (x64 lub x86) dla platformy docelowej biblioteki DLL, a także musisz uważać na kompilacje debugowania. Kompilacja debugowania biblioteki DLL zależy od pliku MSVCR120d.dll, który jest wersją biblioteki do debugowania, która jest instalowana z programem Visual Studio, ale nie przez pakiet redystrybucyjny.
źródło
debug
binarnego, wersja redystrybucyjna C ++ runtime musi być dokładnie taka sama, jak ta, w której ją zbudowałeś.To jest `` kludge '', ale możesz go przynajmniej użyć do przetestowania poczytalności: Spróbuj zakodować na stałe ścieżkę do biblioteki DLL w swoim kodzie
Powiedziawszy to; w moim przypadku działanie
dumpbin /DEPENDENTS
zgodnie z sugestią @ anthony-hayward i skopiowanie ponad 32-bitowych wersji bibliotek DLL wymienionych tam do mojego katalogu roboczego rozwiązało ten problem.Wiadomość jest trochę myląca, ponieważ to nie jest „moja” biblioteka dll, której nie można załadować - to zależności
źródło
Biblioteka DLL musi znajdować się w folderze bin.
W Visual Studio dodaję dll do mojego projektu (NIE w References, ale „Dodaj istniejący plik”). Następnie ustaw właściwość „Kopiuj do katalogu wyjściowego” dla biblioteki dll na „Kopiuj, jeśli nowsza”.
źródło
Spróbuj wprowadzić pełną ścieżkę dll. Jeśli to nie zadziała, spróbuj skopiować dll do folderu system32.
źródło
Upewnij się, że wszystkie zależności Twojej własnej biblioteki DLL są obecne w pobliżu biblioteki DLL lub w
System32
.źródło
Jest jedna bardzo zabawna rzecz (i ma to techniczne znaczenie), która może zmarnować twoje godziny, więc pomyśl o udostępnieniu jej tutaj -
Stworzyłem projekt aplikacji konsoli
ConsoleApplication1
i projekt biblioteki klasClassLibrary1
.Cały kod, który tworzył p / invoke, był obecny w
ClassLibrary1.dll
. Tak więc przed debugowaniem aplikacji z Visual Studio po prostu skopiowałem niezarządzany zestaw C ++ (myUnmanagedFunctions.dll
) do\bin\debug\
kataloguClassLibrary1
projektu, aby można go było załadować w czasie wykonywania przez CLR.Ciągle otrzymywałem
błąd przez godziny. Później zdałem sobie sprawę, że wszystkie takie niezarządzane asemblery, które mają zostać załadowane, muszą zostać skopiowane do
\bin\debug
katalogu projektu startowego,ConsoleApplication1
który zwykle jest formularzem win, konsolą lub aplikacją internetową.Więc bądź ostrożny
Current Directory
w zaakceptowanej odpowiedzi faktycznie oznaczaCurrent Directory
główny plik wykonywalny, z którego rozpoczyna się proces aplikacji. Wygląda na oczywistą rzecz, ale czasami może tak nie być.Wyciągnięta lekcja - Zawsze umieszczaj niezarządzane biblioteki DLL w tym samym katalogu, co plik wykonywalny startowy, aby upewnić się, że można go znaleźć.
źródło
bin\Debug
iobj\Debug
katalogów i ciśgle sekcji „Nie można DLL load”Włącz rejestrowanie fuzji, zobacz to pytanie, aby uzyskać wiele porad, jak to zrobić. Debugowanie problemów z ładowaniem aplikacji w trybie mieszanym może być prawdziwym problemem. Rejestrowanie fuzji może być bardzo pomocne.
źródło
Upewnij się, że ustawiłeś element docelowy platformy kompilacji na x86 lub x64, aby był zgodny z biblioteką DLL - która może zostać skompilowana dla platformy 32-bitowej.
źródło
Jeśli projekty DLL i .NET są w tym samym rozwiązaniu i chcesz skompilować i uruchomić oba za każdym razem, możesz kliknąć prawym przyciskiem myszy właściwości projektu .NET, Zdarzenia kompilacji, a następnie dodać coś podobnego do następującego do zdarzenia po kompilacji wiersz poleceń:
Jest to w zasadzie linia DOS i możesz dostosować ją w zależności od tego, gdzie budowana jest biblioteka DLL.
źródło
Miałem ten sam problem, kiedy wdrożyłem moją aplikację do testowania komputera. Problem polegał na tym, że komputer deweloperski miał
msvcp110d.dll
imsvcr110d.dll
nie komputer testowy.Dodałem moduł scalający „Visual Studio C ++ 11.0 DebugCRT (x86)” w InstalledSheild i zadziałał. Mam nadzieję, że będzie to pomocne dla kogoś innego.
źródło
W moim przypadku jedna niezarządzana biblioteka dll była zależna od innej, której brakowało. W takim przypadku błąd wskaże istniejącą bibliotekę dll zamiast brakującej, co może być naprawdę mylące.
Tak właśnie stało się w moim przypadku. Mam nadzieję, że to pomoże komuś innemu.
źródło
Myślę, że twoja niezarządzana biblioteka potrzebuje manifestu.
Oto jak dodać go do swojego pliku binarnego. i tutaj dlaczego.
Podsumowując, kilka wersji biblioteki redystrybucyjnej może być zainstalowanych w twoim pudełku, ale tylko jedna z nich powinna odpowiadać twojej aplikacji i może nie być domyślna, więc musisz powiedzieć systemowi, jakiej wersji potrzebuje twoja biblioteka, dlatego manifest.
źródło
Konfiguracja : 32-bitowy system Windows 7
Kontekst : Zainstalowałem sterownik PCI-GPIB, przez który nie mogłem się komunikować z powodu wspomnianego problemu.
Krótka odpowiedź : Zainstaluj ponownie sterownik.
Długa odpowiedź : Użyłem również Dependency Walker , który zidentyfikował kilka brakujących modułów zależności. Od razu pomyślałem, że to musiała być nieudana instalacja sterownika. Nie chciałem sprawdzać i przywracać każdego brakującego pliku.
Fakt, że nie mogłem znaleźć dezinstalatora w obszarze Programy i funkcje Panelu sterowania, jest kolejnym wskaźnikiem złej instalacji. Musiałem ręcznie usunąć kilka plików * .dll w katalogu \ system32 i klucze rejestru, aby umożliwić ponowną instalację sterownika.
Problem rozwiązany.
Nieoczekiwaną częścią było to, że nie wszystkie moduły zależności zostały rozwiązane. Niemniej jednak można teraz odwołać się do interesującego nas pliku * .dll.
źródło
Natknąłem się na ten sam problem, w moim przypadku miałem dwie 32-bitowe szt. Jeden z zainstalowanym .NET4.5, a drugi to świeży komputer.
moja 32-bitowa dll cpp (kompilacja w trybie wydania) działała dobrze z zainstalowanym komputerem .NET, ale nie na nowym komputerze, na którym pojawił się poniższy błąd
Wreszcie,
źródło
Napotkano również ten sam problem podczas korzystania z niezarządzanego pliku dll c / c ++ w środowisku C #.
1.Sprawdzono kompatybilność biblioteki dll z procesorem 32-bitowym lub 64-bitowym.
2.Sprawdzono poprawne ścieżki do folderu DLL .bin, system32 / sysWOW64 lub podaną ścieżkę.
3.Sprawdzono, czy brakuje plików PDB (Baza danych programów). Ten film wideo daje najlepsze zrozumienie plików pdb.
Podczas uruchamiania 32-bitowego kodu binarnego C / C ++ w systemie 64-bitowym może to wynikać z niezgodności platformy. Możesz to zmienić w Build> Configuration manager.
źródło
Napotkałem ten sam problem podczas importu C ++ Dll w .Net Framework +4, odznaczyłem Project-> Properties-> Build-> Prefer 32-bit i rozwiązałem go dla mnie.
źródło