Release Modus: DLL wird nicht geladen



  • Hallo,

    ich hab ein Problem mit dem MSVC 2008:

    Mein Programm benutzt eine selbst geschriebene DLL, die über die passende .lib Datei dazugelinkt wird. Wenn ich das Programm im Debug Modus compiliere klappt das auch wunderbar.
    Wenn ich aber im Release Modus bin, wird die DLL nicht geladen. Das äußert sich darin, dass beim ersten Aufruf einer Funktion aus der DLL das ganze mit einer Access Violation abbricht.
    Meine DLL steht nicht in der Liste der geladenen Module, auch die DLL Anzeige vom Process Explorer zeigt sie nicht an.
    In den Project Properties wird die passende lib Datei für beide Modi angeführt, das ganze Compiliert wunderbar im Release Modus und auch der Linker beschwert sich nicht.
    Nur scheint irgendwie jegliche Referenz zu der DLL zu fehlen...

    Abgesehen von den Optimierungen sieht der Aufruf von Compiler und Linker gleich aus, an den Einstellungen hab ich auch nicht großartig rumgespielt.

    Hat irgendjemand ne Idee, was man da machen kann?

    Danke schonmal,
    Kuchen



  • Normalerweise, wenn du die DLL über eine .lib einbindest, kommt sofort beim Programmstart die Fehlermeldung DLL xy konnte nicht geladen werden.
    Ist das nicht der Fall, wurde die DLL geladen.

    Klingt für mich eher so, als wurde die DLL geladen, die Funktion aufgerufen und dann geht etwas schief.

    Einfach mal etwas loggen in der DLL Funktion.
    dependency walker befragen.



  • ihoernchen schrieb:

    Normalerweise, wenn du die DLL über eine .lib einbindest, kommt sofort beim Programmstart die Fehlermeldung DLL xy konnte nicht geladen werden.
    Ist das nicht der Fall, wurde die DLL geladen.

    Es wird nicht mal versucht die DLL zu laden, laut dem Process Monitor findet kein einziger Zugriff auf die Datei statt. Das ist es ja, was das Problem so komisch macht...

    Klingt für mich eher so, als wurde die DLL geladen, die Funktion aufgerufen und dann geht etwas schief.

    Die Funktion wird nicht aufgerufen, sie befindet sich nichtmal im Speicher.
    Wenn man sich das ganze auf Assembler ebene ansieht, werden erst die beiden Parameter auf den Stack gepusht, dann gibts einen call zu der Funktion. An dieser Stelle bricht das ganze mit der Access Violation ab, an der Adresse der Funktion (an die der call Aufruf springen will) steht nichts.

    Einfach mal etwas loggen in der DLL Funktion.
    dependency walker befragen.

    Der zeigt die DLL auch nicht an.
    In der Debug Version ist direkt der erste Eintrag die gewünschte 'LIBUNIT.DLL', in der Release Version taucht die gar nicht auf.

    Ich hab auch mal den Linker mit /VERBOSE aufgerufen, sowohl in der Debug als auch in der Release Version zeigt er an, dass er Funktionen in der passenden .lib Datei findet.


  • Mod

    Dann hast Du evtl. in der Release Version eine statische LIB gebaut und keine DLL!

    Wenn Depends nichts anzeigt von Deiner DLL, dann hast Du auch keine DLL eingebunden...



  • Ich benutz für beide Versionen die selbe LIB/DLL.

    Die DLL wird per
    gcc -O2 -std=c99 -Wall -Wextra -mms-bitfields -mno-cygwin -shared -o libunit.dll unitlib.c -Wl,--out-implib,libunit.lib
    erzeugt.

    Das ganze läuft unter Windows 7 x64, die DLL liegt wahlweise im Verzeichnis des Programms, in C:\Windows oder in C:\Windows\SysWOW64.

    Vielleicht helfen die Parameter für den Linker:

    Debug

    /OUT:"G:\Programmieren\src\EinheitenRechner\Debug\EinheitenRechner.exe" /INCREMENTAL /NOLOGO /MANIFEST /MANIFESTFILE:"Debug\EinheitenRechner.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"g:\Programmieren\src\EinheitenRechner\Debug\EinheitenRechner.pdb" /SUBSYSTEM:WINDOWS /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT libunit.lib

    Release

    /OUT:"G:\Programmieren\src\EinheitenRechner\Release\EinheitenRechner.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"Release\EinheitenRechner.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"g:\Programmieren\src\EinheitenRechner\Release\EinheitenRechner.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /LTCG /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT libunit.lib

    Muss ich bei den Release-Konfigurationen noch irgendwie einstellen, das DLLs geladen werden sollen?



  • DerKuchen schrieb:

    Muss ich bei den Release-Konfigurationen noch irgendwie einstellen, das DLLs geladen werden sollen?

    Nein, mit der eingebundenen lib versucht er die direkt beim Programmstart zu laden.

    Ich würde mal folgendes probieren:
    Kleines Programm, das die DLL mit LoadLibrary lädt und GetProcAddress verwendet. Fehler auswerten (GetLastError).



  • ihoernchen schrieb:

    DerKuchen schrieb:

    Muss ich bei den Release-Konfigurationen noch irgendwie einstellen, das DLLs geladen werden sollen?

    Nein, mit der eingebundenen lib versucht er die direkt beim Programmstart zu laden.

    Ich würde mal folgendes probieren:
    Kleines Programm, das die DLL mit LoadLibrary lädt und GetProcAddress verwendet. Fehler auswerten (GetLastError).

    Hab ich gemacht:

    HMODULE lib = LoadLibrary("libunit.dll");
    	if (!lib) {
    		cout << "LoadLibrary failed: " << GetLastError() << endl;
    		return 1;
    	}
    
    	void *proc = GetProcAddress(lib, "ul_init");
    	if (!proc) {
    		cout << "GetProcAddress failed: " << GetLastError() << endl;
    		return 1;
    	}
    	cout << proc << endl;
    
    	cout << "Funktionier alles )-:" << endl;
    
    	FreeLibrary(lib);
    

    Sowohl im Debug, als auch im Release Modus funktionieren sowohl LoadLibrary als auch GetProcAddress.

    Aber selbst ein minimal Programm, dass die DLL über ihre LIB Datei einbindet stürzt im Release Modus aus dem selben Grund ab.
    Bei letzterem gabs gerade eine Warnung:

    1>libunit.lib(d000025.o) : warning LNK4078: multiple '.text' sections found with different attributes (E0300020)

    Die kommt sowohl im Debug, als auch im Release Modus, ich weiß nicht ob es überhaupt irgendwas bedeutet.





  • Daran hats gelegen.
    Ich erstell die LIB jetzt per
    gcc ... -Wl,--output-def,libunit.def
    lib.exe /DEF:libunit.def /OUT:libunit.lib
    und jetzt funktioniert es auch 🙂

    Vielen Dank für die Hilfe!


Log in to reply