2010-05-27 11 views
6

Mam natywną bibliotekę DLL, która jest wtyczką do innej aplikacji (takiej, z której mam praktycznie zerową kontrolę). Wszystko działa doskonale, dopóki nie połączę się z dodatkowym plikiem .lib (łączy moją bibliotekę DLL z inną biblioteką DLL o nazwie ABQSMABasCoreUtils.dll). Ten plik zawiera dodatkowe API z aplikacji nadrzędnej, którą chciałbym wykorzystać. Nie napisałem nawet żadnego kodu, aby użyć żadnej z wyeksportowanych funkcji, ale właśnie tworzenie linków w tej nowej bibliotece DLL powoduje problemy. W szczególności pojawia się następujący błąd podczas próby uruchomienia programu:Problemy z importowaniem DLLów Win32 (DllMain)

Aplikacja nie została poprawnie zainicjowana (0xc0000025). Naciśnij "OK" aby zamknąć aplikację.

Wierzę, że przeczytałem gdzieś, że jest to zwykle spowodowane funkcją DllMain zwracającą FALSE. Ponadto, po napisaniu wiadomości do standardowego wyjścia:

BŁĄD: alokacja pamięci próbę przed inicjalizacji komponentu

Jestem prawie 100% pewien, że ten komunikat o błędzie jest pochodzących z aplikacji i nie jest to jakiś rodzaj Błąd systemu Windows.

Patrząc na to trochę więcej (aka wymachując wokół i przerzucanie każdy przełącznik wiem) I połączone z/MAP włączona i znalazłem to w wynikowym pliku .map:

0001:000af220  [email protected]@Z    00000001800b0220 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 
0001:000af226  [email protected][email protected]    00000001800b0226 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 
0001:000af22c  [email protected][email protected]   00000001800b022c f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 
0001:000af232  [email protected]@Z    00000001800b0232 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll 

Gdybym undecorate tych nazwy używając „undname” dają następujące (sam kolejności):

void __cdecl operator delete(void * __ptr64) 
void * __ptr64 __cdecl operator new(unsigned __int64) 
void * __ptr64 __cdecl operator new[](unsigned __int64) 
void __cdecl operator delete[](void * __ptr64) 

nie jestem pewien, czy rozumiem, jak coś z ABQSMABasCoreUtils.dll może istnieć w tym pliku .map lub dlaczego mój DLL nawet próby załadowania ABQSMABasCoreUtils.dll jeśli nie mam żadnego kodu, który odwołuje się es tej biblioteki DLL. Czy ktoś może mi pomóc ułożyć te informacje razem i dowiedzieć się, dlaczego to nie działa? Za to, co jest warte, potwierdziłem przez "dumpbin", że aplikacja nadrzędna importuje ABQSMABasCoreUtils.dll, więc jest ładowana bez względu na wszystko. Próbowałem również opóźnienia ładowania tego DLL w mojej DLL, ale to nie zmieniło wyników.

EDIT

I dwukrotnie sprawdzane i wszystkie pliki związane są 64-bitowe.

+1

Czy próbowałeś użyć 'LoadLibrary' zamiast statycznego łączenia biblioteki importu? Jeśli to zrobisz, główna aplikacja zostanie już zainicjalizowana i masz pewną przewagę. – Oleg

+0

Pomyślałem o tym, ale w końcu wykorzystam dużą liczbę funkcji z tej biblioteki. Czy nie będę musiał używać GetProcAddress dla każdego z nich? Wolałbym tego uniknąć, jeśli to możliwe. – brady

+1

C0000025 = STATUS_NONCONTINUABLE_EXCEPTION. Spróbuj uruchomić aplikację w trybie windbg i zobacz, gdzie się zawiesza; może to da ci wskazówkę. – Luke

Odpowiedz

5

Po prostu miałem dokładnie ten sam problem. Jest to problem związany z interfejsem API Abaqus, a nie z ładowaniem biblioteki DLL.

Myślę, że dzieje się tak dlatego, że API Abaqus zastępuje nowe i usuwa funkcje (jak się wydaje zauważyliście). Jeśli zadzwonisz nowe lub usuwać w programie przed inicjalizacji API ABAQUS, takich jak wywołując odb_initializeAPI(); wtedy masz

BŁĄD: przydział pamięci próbę przed inicjalizacji komponentu

komunikat o błędzie i awarie programu .

W moim programie, wywołanie odb_initializeAPI(); przed pierwszym new rozwiązało problem.

+1

Minęło trochę czasu odkąd to naprawiłem, ale miałem trochę inny problem. Faktycznie uzyskiwałem dostęp do ODB w podprogramie użytkownika, więc używałem getActiveOdb(). Otrzymałem ten błąd, ponieważ kompilowałem z zależnością od msvcr90.dll i Abaqus korzystał z msvcr80.dll. Ale cieszę się, że opublikowałeś powyższe informacje - ciężko jest znaleźć szybką pomoc online dla podprogramów użytkownika i postprocesorów Abaqus. – brady

+0

@brady Jak zidentyfikowałeś i rozwiązałeś problem zależności? Wierzę, że 'msvcr100.dll' jest w konflikcie z' msvcr80.dll' w moim programie. Byłbym wdzięczny za pomoc. – Derek

+1

Nie pamiętam, jak ją zidentyfikowałem - prawdopodobnie użyłem narzędzia "dumpbin/imports" i zauważyłem redundantne biblioteki uruchomieniowe C++. Aby rozwiązać ten problem, musiałem skompilować program Visual C++ 8.0 (Visual Studio 2005), który był obsługiwanym kompilatorem C++ dla tej wersji Abaqus. Możesz zobaczyć obsługiwane kompilatory tutaj: [Wymagania systemowe Abaqus] (http://www.3ds.com/support/certified-hardware/simulia-system-information/). Wybierz odpowiednią wersję i kliknij Wymagania systemowe, wybierz platformę i wyszukaj wymagania kompilatora C++. – brady

0

Plik ABQSMABasCoreUtils.dll wygląda tak, jakby importował funkcje 64-bitowe. Czy twoja biblioteka dll również jest 64-bitowa? Jeśli nie, to jest problem - nie można mieszać bibliotek DLL skompilowanych dla różnych architektur w tym samym procesie.

+0

Jeśli tak było, kod nie powiedzie się skompilować - nie zawiedzie w czasie wykonywania. –

2

Cóż, na pewno odwołasz się do importu tej biblioteki. Trudno napisać program w C++ bez użycia operatora new lub delete. Radzenie sobie z oprogramowaniem innych firm, które uważa, że ​​musi zastąpić wersję CRT tych operatorów, jest wystarczająco trudne, niemożliwe, aby nie pozwalało na wywoływanie ich, dopóki nie uzna, że ​​czas jest właściwy. Porzuć wszelką nadzieję lub odszukaj pomoc od sprzedawcy.

+1

Czy popularne programy w C++ często zastępują takie popularne operatory? To wydaje się głupie. Czy można to obejść za pomocą/DEFAULTLIB? – brady

+2

Jest to powszechne tylko w programach głupich i bibliotekach stylów bazowych, które liczą na łączenie się z nimi wszystkich kodów. Nie możesz tego obejść. Hackowanie .lib przyniesie tylko smutek, gdy jakiś kod używa alokatora, a inny kod nie. To jest automatyczny wyciek pamięci lub AV. –

1

Jedną z możliwych przyczyn błędu podczas ładowania pliku ABQSMABasCoreUtils.dll jest to, że nie można znaleźć modułu zależności (włącznie z opóźnionymi wczytanymi bibliotekami DLL). Użyj Dependency Walker (patrz http://www.dependencywalker.com/), aby zbadać wszystkie zależności ABQSMABasCoreUtils.dll.

mam dwie propozycje:

  1. Sprawdź, czy można załadować ABQSMABasCoreUtils.dll z tytułu LoadLibrary. Nie potrzebujesz wywoływać żadnej funkcji z ABQSMABasCoreUtils.dll. Użycie LoadLibrary Nie widzę jako rozwiązania końcowego. To tylko test diagnostyczny. Za pomocą testu możesz sprawdzić, czy masz jakiś ogólny problem z ładowaniem ABQSMABasCoreUtils.dll w twoim programie lub masz jakiś problem z inicjalizacją procesu.
  2. Jeśli załadowanie pliku ABQSMABasCoreUtils.dll w odniesieniu do LoadLibrary zakończy się niepowodzeniem, należy użyć funkcji profilowania Dependency Walker do protokołu wszystkich wywołań wykonanych podczas ładowania pliku ABQSMABasCoreUtils.dll. Innym sposobem byłoby użycie Monitora procesu (zobacz http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx), aby prześledzić, jakie operacje na plikach i rejestrach będą wykonywane podczas ładowania pliku ABQSMABasCoreUtils.dll.

Jeśli nie powiodło się LoadLibrary, to naprawdę masz problem z inicjalizacją bibliotek DLL. Zazwyczaj problem występuje, jeśli biblioteka DLL wewnątrz DllMain spróbuje użyć funkcji z innej biblioteki DLL, która nie została jeszcze zainicjalizowana (jeszcze nie wraca z DllMain). Przed rozpoczęciem diagnostyki tego problemu należy spróbować wykluczyć bardziej proste problemy z LoadLibrary.

Powiązane problemy