C++ Runtime Version rausfinden



  • Hallo zusammen,

    ich suche eine Möglichkeit, wie ich die Version der aktuell verwendeten C++ runtime DLLs herausfinden kann.
    Auf dem Rechner können schließlich mehrere installiert sein, und ich suche eine einfache Lösung, wie ich das aus dem Code heraus rausfinden kann (evtl. sind dafür Makros definiert?) (_MSC_VER ist dafür nicht geeignet, da es nur die Version von VS beinhaltet)

    Danke & schönen Gruß

    Mark



  • Wofür musst du das wissen?



  • Ich will prüfen, ob der Aufrufer meiner DLL binär-kompatibel ist.
    Leider ist das je nach verwendeter C++ Runtime Library nicht gegeben (z.B. ein VS2005 std::list ist nicht Kompatibel mit einem VS2008 std::list).

    Und da ich von einem DAU - Kunden ausgehen muss, reicht eben nicht die Info "DLL nur kompatibel mit VS2008"

    Leider macht sich diese Inkompatibilität in der Regel sehr seltsam bemerkbar und kostet viel Zeit beim Debuggen.



  • Sry aber das klingt mir extrem nach Hack. Binärkompatibilität ist unter Umständen schon kaputt wenn der Aufrufer nur mit ein paar anderen #defines kompiliert wurde, da kann er auch gern lange noch die exakt gleiche CRT Version haben. In ein dll Interface gehören nur primitive Typen, alles andere ist per Defintion inkompatibel...



  • Super...das hilft mir sehr...
    Du kannst gerne vorbeikommen und ein paar Millionen lines-of-code bearbeiten, ich wäre dir dankbar 😉

    Aber das sind eben die Gegebenheiten und ich suche eine Lösung - dass das Problem "house-made" ist, ist mir auch bekannt.

    Ich bitte also nur Lösungen, die das ursprüngliche Thema betreffen und nicht wie man das Problem generell umgehen könnte - da sind wir schon dran...



  • Ja wie gesagt: Es gibt keine Lösung (zumindest soweit mir bekannt ist). Selbst wenn du einen Weg finden würdest die CRT Version des Aufrufers abzufragen (z.B. indem du die vom Prozess geladenen Module nach den CRT dlls durchsuchst und deren Versionsinfo abfrägst) ist dies eben keine hinreichende Bedingung für Binärkompatibilität, sagt eigentlich überhaupt gar nix drüber aus (z.B. die ganzen Container wie std::list sind ja nicht in diesen dlls). Sobald nur ein paar andre Compilerflags am Werk waren ists schon wieder aus und der Aufrufer könnte die CRT übrigens auch statisch linken oder überhaupt eine komplett andere Implementierung der Standardbibliothek (stlport, etc.) benutzen...

    Wenn es dir nur um Container geht wäre es vielleicht eine Lösung eine eigene Implementierung der Container mitzuliefern und diese statt der std:: Container zu verwenden. So könntest du zumindest eingeschränkt Binärkompatibilität sicherstellen...



  • Jo da sind wir schon dabei 🙂

    Meine Lösung wäre für die Zwischenzeit (wiegesagt, die Bibliothek ist riesig und die Änderung ist nun mal nicht produktiv ergo geringe Prio)

    Schade, ich hätte gehofft es gäbe sowas wie GetRuntimeVersion() :p



  • pub00515 schrieb:

    Schade, ich hätte gehofft es gäbe sowas wie GetRuntimeVersion() :p

    Wie gesagt, selbst wenn es das gäbe würde es dir nichts bringen...

    pub00515 schrieb:

    Jo da sind wir schon dabei 🙂

    Beachtet dabei vielleicht dass sich die Implementierung der im Interface verwendeten Container dann ausschließlich in eurer dll befindet, ansonsten bricht am Ende wieder alles zusammen sobald der Benutzer z.B. sein struct packing umstellt...


  • Mod

    pub00515 schrieb:

    Schade, ich hätte gehofft es gäbe sowas wie GetRuntimeVersion() :p

    Und es würde Dich kein Stück weiterbringen. Denn woher weißt Dumit welchem Application Kontext (Manifest) die exe gestartet wurde, bzw. die DLL geladen wurde?

    Theoretisch ist es möglich, dass ein Prozess mehrere Versionen der VS-2005/8 CRT Runtimes und MFC DLLs lädt.

    Welchen Nutzen sollte es auch haben, denn Deine EXE/DLL bindet ja exakt gegen eine DLL oder statisch und das ist ja bereits zur Zeit des Compile Vorgangs bekannt. Denn in diesem Moment werden die Abhängigkeiten und Manifeste erzeugt.

    Das ändert sich zur Laufzeit nicht mehr...



  • Für alle die es interessiert:

    mit dem Makro _CRT_ASSEMBLY_VERSION kriegt man die verwendete runtime.
    Damit funktioniert meine Überprüfung soweit.

    Für alle Skeptiker:

    ich weiß, das ist keine 100%ige Lösung. Aber da ich derjenige bin, der beim Kunden debuggen muss, weiß ich, woran es liegt. Und diese Lösung, kombiniert mit anderen checks, deckt eben 90% aller Fehler ab. Und das reicht mir erstmal.

    Gruß



  • pub00515 schrieb:

    mit dem Makro _CRT_ASSEMBLY_VERSION kriegt man die verwendete runtime.

    Damit bekommst du nur die Version der Runtime gegen die du gerade kompilierst, mit der Version des Aufrufers hat das überhaupt nix zu tun!? Und wie gesagt, das zu checken bringt genau so viel wie es nicht zu tun...

    EDIT: Ok wenn du in deine Header ein #error machst falls die Version nicht stimmt hast du effektiv den Kunden auf eine CRT Version festgenagelt, aber wie gesagt, Binärkompatibilität ist damit genauso sichergestellt wie ohne...



  • Richtig, aber wenn das Makro einmal in der DLL aufgerufen und zwischengespeichert wird und dann beim Kunden im Header mit der kompilierten Version verglichen wird, kriegt man das raus. Mich interessiert nur, ob der Kunde gegen die gleiche CRT kompiliert wie wir das tun.



  • Jop, das stimmt. Ich mein ok, es reduziert den Raum möglicher Fehler um eine Dimension, trotzdem ist die CRT Version für Binärkompatibilität eigentlich absolut irrelevant. Aber wenn ihr irgendwie damit auskommt ist es ja schonmal was^^



  • Ja eben 🙂



  • Ich verstehe noch immer das Problem noch nicht....

    In VS2005/2008 ist es so:
    Wenn Du eine Applikation oder DLL entwickelst, dann legst *DU* fest mit welcher CRT Version diese laufen soll. Dann wird für diese CRT-version ein Manifest in Deine EXE/DLL eingebettet. Somit wird *sichergestellt*, dass immer diese CRT-VERsion auch verwendet wird! Es kann also vorkommen, dass in einer APPLikation verschiedene Versionen einer cRT laufen.

    Wenn Du damit Probleme hast, solltest Du diese mal erklären.... es gibt eigentlich nur zwei problemfälle:
    1. DU hast die falsche CRT-Version in Deinem Manifest stehen
    2. Du hast keine reine POD-C-SChnittstelle und übergibst Speicher/Objekte über DLL Grenzen hinweg und der andere verwendet eine andere CRT-VErsion in seinem manifest

    Das letzte könntest DU durch prüfen des Activation-Context herausfinden...

    In VS2010 ist das ganze wieder anders... da kannst DU einfach die VErsion der CRT-dLL prüfen, da es keine manifeste mehr gibt.



  • Jochen Kalmbach schrieb:

    In VS2010 ist das ganze wieder anders... da kannst DU einfach die VErsion der CRT-dLL prüfen, da es keine manifeste mehr gibt.

    Wtf tatsächlich!?


Anmelden zum Antworten