Probleme mit statischer Bibliothek im Debug-Modus



  • Vielen Dank für deine Hilfe.

    Ich hab jetzt bei dem Projekt, das die Lib erstellt, die CRT statisch eingebunden (/MT bzw. /MTd) und meine Makros folgendermassen angepasst:

    #ifndef CREATING_LIB	// nur beim Benutzen des Headers, nicht bei Erstellung der Bibliothek
     #ifdef _DEBUG
      #pragma message("Automatisches Linken mit Fraction-d.lib (Debug)")
      #pragma comment(linker, "/NODEFAULTLIB:MSVCRTD")
      #pragma comment(lib, "Fraction-d.lib")
     #else
      #pragma message("Automatisches Linken mit Fraction.lib (Release)")
      #pragma comment(linker, "/NODEFAULTLIB:LIBCMT")
      #pragma comment(lib, "Fraction.lib")
     #endif	// _DEBUG
    #endif	// CREATING_LIB
    

    Ist das okay, diese Bibliotheken zu ignorieren? Momentan geht es beim Anwendungsprojekt mit allen Konfigurationen (Release Static, Debug Static, Release DLL, Debug DLL), aber kann man so auf Probleme stossen?

    Wie ist das überhaupt, wenn in der Lib die C-Runtime statisch eingebunden wird und im Anwendungsprojekt dynamisch? Was passiert da schlussendlich?



  • Nur mal so.
    Ich benutze die #pragma Anweisungen nur sehr ungerne. Ich finde das wesentlich komfortabler in den Dialogen einzustellen. Ich passe in einem Projekt bei Portierung lieber mal den Dialog an, als den Code anzufassen.



  • Ja, das habe ich mir auch überlegt. Jedoch wollte ich eigentlich so wenig wie möglich dem Anwender überlassen, sodass es wie bei der Standardbibliothek reicht, einen Header zu inkludieren.

    Was denkst du, wie viele Linkerfehler vermieden werden können, wenn man nicht noch selber Debug/Release und Static-Lib/DLL bei jedem Projekt aufeinander abstimmen muss? Und reden wir jetzt mal nicht von den in Konflikt geratenen Bibliotheken, die man auch noch ignorieren müsste...



  • Nexus schrieb:

    Ist das okay, diese Bibliotheken zu ignorieren? Momentan geht es beim Anwendungsprojekt mit allen Konfigurationen (Release Static, Debug Static, Release DLL, Debug DLL), aber kann man so auf Probleme stossen?

    Nun ja, du müsstest noch weitere Bibliotheken ignorieren, denn der (evtl. sehr unbedarfte) Anwender kann noch andere Konfigurationen eingestellt haben, eine Liste hier:

    http://msdn.microsoft.com/en-us/library/6wtdswk0(VS.80).aspx

    Ich halte von "Ignorieren" nicht sehr viel, das sollte nur letztes Mittel sein, um etwas lauffähiges zu erzeugen.

    Nexus schrieb:

    Wie ist das überhaupt, wenn in der Lib die C-Runtime statisch eingebunden wird und im Anwendungsprojekt dynamisch? Was passiert da schlussendlich?

    Da kann es mehrere Probleme geben, eine kleine (unvollständige) Liste unter "MORE INFORMATION", hier:

    http://support.microsoft.com/kb/140584/en-us

    Da wird auch gezeigt, wie man noch weitere Makros einsetzen kann, damit andere es leichter haben, deine Bibliothek einzusetzen, denkbar wäre mit diesen Makros dann auch, gleich die "richtige" Bibliothek mit #pragma zu setzen, je nach Linkeroption.

    MfG,

    Probe-Nutzer



  • Okay, vielen Dank für die Links.

    Jedoch stimmt das bei der MSDN nicht ganz; ich erhalte immer noch Linkerfehler, wenn ich die Bibliotheken so wie vorgeschrieben ignoriere.

    Und ignorieren ist vielleicht schon nicht ideal, aber gibt es eine bessere Möglichkeit?

    Und heisst das, ich müsste sogar vier statische Bibliotheken erstellen, um eine konsistente Nutzung der CRT zu ermöglichen? Das fände ich langsam ein bisschen übertrieben, zumal ich nur eine kleine Klasse bereitstellen möchte...

    Edit: Ich habs jetzt mal vorläufig so gemacht, das geht mit allen Konfigurationen im Anwendungsprojekt. Die Lib selber linkt statisch mit der CRT, führt das zu oben erwähnten Problemen?

    Also so sehen die sehr übersichtlichen Pragma-Direktiven aus:

    #ifndef CREATING_LIB
     #ifdef _DEBUG
      #ifdef _DLL
       #pragma comment(linker, "/NODEFAULTLIB:LIBCMTD")
      #else
       #pragma comment(linker, "/NODEFAULTLIB:MSVCRTD")
      #endif // _DLL
      #pragma message("Automatisches Linken mit Fraction-d.lib (Debug)")
      #pragma comment(lib, "Fraction-d.lib")
     #else
      #ifdef _DLL
       #pragma comment(linker, "/NODEFAULTLIB:LIBCMT")
      #else
       #pragma comment(linker, "/NODEFAULTLIB:MSVCRT")
      #endif // _DLL
      #pragma message("Automatisches Linken mit Fraction.lib (Release)")
      #pragma comment(lib, "Fraction.lib")
     #endif	// _DEBUG
    #endif	// CREATING_LIB
    

    Aber ich müsste noch mehr Bibliotheken ignorieren... Naja so läufts zumindest bei mir 😉



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Compiler- und IDE-Forum verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Aber wie macht man das am besten, wenn man eine statische Bibliothek zur Verfügung stellen will? Kommt man da nicht drum herum, alle 4 möglichen Kombinationen von Konfigurationen (Debug/Release - CRT statisch/dynamisch gelinkt) einzurichten?

    Oder reicht es, nur auf Debug/Release Rücksicht zu nehmen und z.B. gegen statisch gegen die CRT zu linken?



  • Mach doch einfach verschiedene ProjectDateien.
    So habe ich es bis jetzt immer gehandhabt und hatte keine Probleme damit.



  • Welche Dateien meinst du?

    Momentan stelle ich zwei Bibliotheken (.lib) pro Projekt zur Verfügung, also für Debug- und Releasemodus. Soll ich total 4 pro Projekt erzeugen, um auch noch die CRT-Linkage zu berücksichtigen?



  • 1. Das ignorieren der Default Libs ist meistens nicht das Problem.
    Diese Meldungen passieren fast immer nur, wenn es zwei Objekt Module gibt, die mit unterschiedlichen CRT Enstellungen kompiliert wurden zusammen gelinkt werden.
    Es ist nie gut NODEFAULTLIB zu verwenden. Korrekt ist es mit /VERRBOSE das schuldige Objekt Modul zu finden.
    2. Ich halte pragmas comment lib immer für den besseren Weg.



  • Okay, momentan habe ich es so gelöst, dass beim Linken mit der falschen CRT-Version über #error ein Fehler ausgelöst wird. Doch so wird der Anwender gezwungen, dynamisch gegen die CRT zu linken.

    Jetzt habe ich 2 statische Bibliotheken pro Projekt (Debug/Release). Wenn ich eine statische Linkage gegen die CRT auch ermöglichen will, komme ich nicht darum herum, total 4 Libs zu erstellen?



  • Nexus schrieb:

    Jetzt habe ich 2 statische Bibliotheken pro Projekt (Debug/Release). Wenn ich eine statische Linkage gegen die CRT auch ermöglichen will, komme ich nicht darum herum, total 4 Libs zu erstellen?

    Kann man dann eigentlich so eine Header-Datei machen:

    #ifdef _DEBUG
    #    ifdef _DLL
    #       pragma comment( lib, "bla_debug_dynamic_crt.lib" )
    #    else
    #       pragma comment( lib, "bla_debug_static_crt.lib" )
    #    endif
    #else
    #    ifdef _DLL
    #       pragma comment( lib, "bla_release_dynamic_crt.lib" )
    #    else
    #       pragma comment( lib, "bla_release_static_crt.lib" )
    #    endif
    #endif
    

    ? Oder wie wird das normalerweise gemacht, manuell die Bibliothek angeben lassen? Gibt's bei so 'ner Header-Datei Nachteile?

    edit: Das hier ginge auch 🙂

    #ifdef _DEBUG
    #    define LIBINC_DBG_REL "debug"
    #else
    #    define LIBINC_DBG_REL "release"
    #endif
    
    #ifdef _DLL
    #    define LIBINC_STAT_DYN "dynamic"
    #else
    #    define LIBINC_STAT_DYN "static"
    #endif
    
    #pragma comment( lib, "bla_" LIBINC_DBG_REL "_" LIBINC_STAT_DYN ".lib" )
    #undef LIBINC_DBG_REL
    #undef LIBINC_STAT_DYN
    


  • Ja, momentan hab ichs aber eben auf dynamische CRT-Linkage eingeschränkt, um zwei verschiedene Konfigurationen zu vermeiden:

    #ifndef _DLL
     #error Muss dynamisch gegen die CRT gelinkt werden.
    #endif
    
    #ifdef _DEBUG
     #pragma message("Automatisches Linken mit Fraction-d.lib (Debug)")
     #pragma comment(lib, "Fraction-d.lib")
    #else
     #pragma message("Automatisches Linken mit Fraction.lib (Release)")
     #pragma comment(lib, "Fraction.lib")
    #endif
    

    Also besteht die einzige Möglichkeit doch darin, vier statische Bibliotheken bereitzustellen?



  • Sorry, wenn ich die Frage zum fünften Mal stelle 😉
    Gibt es keine andere Möglichkeit, als 4 statische Bibliotheken (.lib) zu erstellen, wenn man sowohl dynamische als auch statische CRT-Linkage und auch Debug- und Release-Modus ermöglichen will?



  • Nexus schrieb:

    Gibt es keine andere Möglichkeit, als 4 statische Bibliotheken (.lib) zu erstellen, wenn man sowohl dynamische als auch statische CRT-Linkage und auch Debug- und Release-Modus ermöglichen will?

    Ich bin mir zumindest relativ sicher, dass es nicht anders geht. Nicht zu vergessen, diese 4 Libs übrigens ja nur pro Compilerversion 😃



  • Badestrand schrieb:

    Nicht zu vergessen, diese 4 Libs übrigens ja nur pro Compilerversion 😃

    Und ich dachte, statische Bibliotheken wären ein guter Weg zur Wiederverwendung von Code... 🙄

    Wahrscheinlich werde ich den Benutzer einfach zwingen, MSVC++ mit dynamischer CRT-Linkage zu verwenden... 😃

    Aber wie ist das bei anderen Bibliotheken, z.B. Boost, gelöst? Gibt es da für alle existierenden Compiler eigene Libs?



  • Nein! Es gibt IMHO keine andere Möglichkeit.
    Statisch/Dynamisch, Debug/Non-Debug macht leider 2x2=4
    Und das je Compiler Version...



  • Okay, danke für die Antworten.
    Dann werd ich mir das halt wohl oder übel antun müssen. 😞

    Naja, so viel zu Code-Wiederverwendung... Irgendwie beschleicht mich das Gefühl, eine eigene CPP-Datei statt einer Lib mitzuliefern wäre einfacher... 🙄



  • Nexus schrieb:

    Naja, so viel zu Code-Wiederverwendung... Irgendwie beschleicht mich das Gefühl, eine eigene CPP-Datei statt einer Lib mitzuliefern wäre einfacher... 🙄

    Warum lieferst Du nicht eine DLL aus, und dazu eine Import-LIB?



  • Martin Richter schrieb:

    Warum lieferst Du nicht eine DLL aus, und dazu eine Import-LIB?

    Aber für die Import-Lib hätte man wieder das gleiche Problem, oder?


Anmelden zum Antworten