Wie kann ich herausfinden, was meine Anwendung die statisch und dynamisch verknüpften CRT macht mischen

StackOverflow https://stackoverflow.com/questions/1569222

Frage

Sorry für den langen Post, die folgt.

Ich weiß, dass es keine gute Idee ist, die statisch gelinkte und dynamisch verknüpften C und C ++ Runtimes geliefert von Microsoft zu mischen. Unsere Anwendung bei der Arbeit schon mischt sie leider und wir haben versucht, das zu beheben. Aus verschiedenen Gründen (unter denen unfamiliarity mit MSI, die Tatsache, dass wir NSIS verwenden, die vielleicht MSMs nicht gut unterstützen, fehlt es an Zeit und Ressourcen) haben wir beschlossen, die CRTs statisch statt dynamisch zu verknüpfen. Ich kenne die Gründe, warum dies nicht eine gute Idee, aber es war unsere Wahl für jetzt.


Unser Code ist meist Standard C ++ ergänzt durch eine ganze Reihe von anderen Open-Source-Bibliotheken.

Die Struktur der Anwendung ist. Verschiedene Module dieses Ergebnis in statischen Bibliotheken, die sich miteinander verknüpft sind verschiedene Dinge, unter denen eine ausführbare Datei zu erstellen, die uns Probleme geben

In Release bauen wir alle unsere Code mit / MT. Für einen Teil der Open-Source-Bibliotheken wir Binärdateien vorkompilierte und einige von ihnen wurden DLLs mit / MD vorkompilierte, die uns die Laufzeiten mischen gemacht. So wir diese uns mit / MT und machte sie führen in statischen Bibliotheken nicht dlls neu kompiliert. Diese Umwandlung wird nicht für jede Bibliothek gemacht, so dass wir nach wie vor mit einigen DLLs verknüpfen, dass die Verwendung / MD.


Das Ergebnis ist nun, dass in Depends.exe alle unsere Sachen außer einem ausführbaren Datei nicht direkt ist abhängig von msvcr80.dll oder msvcp80.dll. Durch hängt nicht direkt meine ich, dass msvcr80.dll nicht ein Kind der Wurzel des Baumes durch depends.exe gezeigt ist. Manchmal finden wir msvcr80.dll in Mitleidenschaft gezogen durch eine der Bibliothek DLLs, aber das ist ein paar Stufen tiefer in dem Baum.

Wie kann ich herausfinden, warum ist msvcr80.dll auf der ersten Ebene für diese eine nervtötende ausführbar? Was macht diesen ausführbaren Link direkt auf msvcr80.dll?

könnte ein Grund vielleicht sein, dass wir verknüpfen statisch Bibliothek A, welche Anwendungen / MD verbindet so dynamisch mit der CRT verbindet. So ist der Code in Bibliothek A endet in unserem Programm an, damit unsere ausführbaren Links mit msvcr80.dll auf. Aber wie finde ich heraus, welche eine der Bibliotheken das tut?


Was ich versuchte so weit:

  • laden Sie die statisch gelinkte LIB-Dateien in depends.exe -> funktioniert nicht, da depends.exe erwartet eine ausführbare Datei oder DLL nicht eine statische Bibliothek
  • Verwendung Dumpbin.exe / RICHTLINIEN auf den statisch gelinkte LIB-Dateien -> keiner von ihnen zeigten msvcrt80.dll (während in Debug, wo wir versuchen, den Einsatz / MDd für alles, sie zeigt msvcrt80d.dll taten, was macht ich denken das Verfahren ist gut und es beweist, dass alle die statisch gelinkte Open-Source-Bibliotheken korrekt mit / MT kompiliert werden)
  • verwenden Sie die / VERBOSE: LIB-Linker-Flag -> zeigte sich, dass in der Tat in msvcrt.lib es ziehen, die die Importbibliothek für msvcr80.dll ist, so dass wir in Schwierigkeiten sind, aber es hat nicht gesagt, warum es das zu tun
  • verwenden Sie den / VERBOSE Linker-Flag + in Visual Studio: Zusätzliche Abhängigkeiten libcmt.lib + alle Bibliotheken Standard Ignorieren YES + Ignorieren spezifische Bibliothek: msvcrt.lib in einem verzweifelten Versuch zu machen msvcrt.lib weggehen oder sehen, wer es sie zieht . Das Ergebnis verblüfft mich:
    Searching C:\Program Files\Microsoft Visual Studio 8\VC\lib\msvcrt.lib:  
      Found "public: virtual void * __thiscall type_info::`vector deleting destructor'(unsigned int)" (??_Etype_info@@UAEPAXI@Z)  
        Referenced in libcmt.lib(typinfo.obj)  
        Loaded msvcrt.lib(ti_inst.obj)  
            msvcrt.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in libcmt.lib(typinfo.obj)  
            msvcrt.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in libcmt.lib(typinfo.obj)  
      Found "void __stdcall `eh vector destructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *))" (??_M@YGXPAXIHP6EX0@Z@Z)  
        Referenced in msvcrt.lib(ti_inst.obj)
        Loaded msvcrt.lib(ehvecdtr.obj)

Soweit ich verstehe, typinfo.obj in libcmt.lib verweist auf ein Symbol, sucht es in msvcrt.lib und nach findet es in ti_inst.obj es einen Fehler wirft, dass er zweimal definiert wird. Aber das macht keinen Sinn. Wenn libcmt.lib bereits das Symbol hat, warum ist es für sie in msvcrt.lib Suche am Ende und damit msvcr80.dll in meiner ausführbaren Datei zu bringen? Und allgemeine, warum sollte die statische Bibliothek Suche nach Symbolen in der dynamischen Import-Bibliothek? Warum sieht der Linker auch bei msvcrt.lib, wenn ich es in der Ignore spezifischen Bibliothek?

Vielen Dank für Ihre Geduld: -).

War es hilfreich?

Lösung

Ich habe die Lösung für mein Problem. Es war ein dummer Fehler dort links von der Antike wohl.

msvcrt.lib wurde von uns ausdrücklich in den Zusätzliche Abhängigkeiten Feld erwähnt :-( so natürlich ist es die DLL machte eine Abhängigkeit. Und wegen all der Open-Source-Bibliotheken, dass das Feld viel Text hat, so dass wir nicht taten bemerkt es. Und um ehrlich zu sein, wir nicht einmal genau an, dass das Feld der Suche dachten, da wir uns nicht vorstellen sind es so ein grober Fehler in unseren Projekten sein könnte.

Andere Tipps

Öffnen Sie die ausführbare Datei mit depends.exe und den Profiler laufen hängt gebaut in. Ich glaube, dies wird einzuloggen, warum alle Ihre DLLs geladen sind, und von wo aus sie geladen sind. Siehe die „Log Funktion Loadlibrary Anrufe“ aus.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top