mit msvc generierte libs: aeltere MSVC versionen unterstuetzen



  • hi.

    ich habe die situation dass ich eine komponente als statische library ausliefern moechte, für MSVC also 1 .h-file und 1 .lib-file, damit der kunde das selbst einlinken kann.

    da der kunde selbst entscheiden moechte ob er seine finale EXE mit /MD oder /MT linkt, muss ich schonmal 2 libs zur verfuegung stellen (fuer release+debug 4 libs). muss ich dafuer dann aber auch fuer jede MSVC version eine eigene lib erstellen? momentan compile ich mit MSVC9, unterstuetzen diese libs dann auch neuere und aeltere MSVC versionen? oder muss ich fuer jede unterstuetzte MSVC version diese 2 (oder 4) libs generieren?



  • noch was: die lib nutzt eigentlich nur WinAPI funktionen, nichts aus der libc / CRT. zumindest nutze ich selbst keine dieser funktionen. wieso dann immer noch die abhaengigkeit? MSVC scheint die schon noch zu brauchen, da er ne warnung wirft wenn das linken der EXE ne andere CRT benutzt als das compilen der .lib (bzw der .objs in der .lib).



  • Prinzipiell gilt, wenn Du Abhängigkeiten zur CRT hast (das hast Du per Default bei einer LIB), dann musst Du für jede VS-Version (und normalerweise auch jeden SP) eine eigene LIB zur Verfügung stellen, welcher genau mit dieser Version erstellt wurde.

    Wenn Du wirklich unabhängig etwas zur Verfügung stellen willst, dann musst Du eine DLL machen!
    Diese hat dann nur eine Import-LIB, welche dann natürlich keine Dinge in der Schnittstelle verwenden darf, welche in der CRT vorkommen (z.B. kein FILE*); und natürlich dürfen auch Speicherblöcke immer nur in der DLL allokiert und dort auch wieder freigegeben werden.

    Wenn Du wirklich nur eine LIB für alle Compiler haben willst, dann ist dies eigentlich nicht möglich....


  • Mod

    Ich kann mich Jochens Ausführungen nur anschließen:
    Versionsübergreifend kompatibel wirst Du nur mit einer DLL und einer einfachen Schnittstelle, die nur PODs verwendet und zudem Allokationen und Freigaben nur in Deinem Modul geschlossen vornimmt.



  • also, der groesste teil meiner applikation laeuft schon jetzt in einer DLL ab. die LIB ist nur dafuer da, die DLL zu initialisieren, allerdings macht sie noch ein paar extras. beispielsweise ist die kommunikation zwischen DLL und LIB verschluesselt, darum kuemmert sich die LIB auch.

    inzwischen habe ich es geschafft, dass ich nur noch 1 LIB brauche statt 4: mit den switches "/MT /Zl" wird der name der CRT nicht kodiert, dadurch kann man dass dann spaeter mit beliebigen CRT-switches linken.

    das heisst ich muesste pro VC-version (bzw VC-version-und-SP) nur noch 1 lib anbieten.

    allerdings verstehe ich immer noch nicht wozu ich eine CRT einlinken muss. nachdem ich die security switches (/Eh, /GX etc) deaktiviert habe wird auch kein security token / cookie mehr benoetigt. trotzdem braucht er die CRT.

    wieso will der compiler die CRT, wenn ich ausschliesslich funktionen aus Kernel32.lib und User32.lib benutze?



  • Weil die CRT eben nötig ist damit irgendwas läuft. Da sind so Sachen drin wie der Support für Exception Handling und so Zeug. Du kannst auf die CRT verzichten, dann musst das aber alles selbst basteln...



  • Mit viel Aufwand bekommst Du das auch für eine DLL hin... aber ich Frage mich, ob es der Aufwand Wert ist...
    http://blog.kalmbach-software.de/2008/02/02/smallest-application-size-for-win32-console-application/



  • ich will das nicht fuer die DLL hinbekommen. die DLL wird mit einer statischen CRT gelinkt, funktioniert auch alles.

    nur um die LIB geht es mir. die LIB ruft keine funktionen aus der CRT auf, nur aus der Kernel32.lib und der User32.lib. Die LIB initialisiert die DLL mit LoadLibraryA und GetProcAddress. Dabei werden alle Parameter die an die DLL gehen und von der DLL zurueckgegeben werden mit AES verschluesselt/entschluesselt.

    ich habe jetzt mal die LIB durch dumpbin gejagt, und so wie es aussieht werden keine CRT-funktionen mehr benutzt (durch das abschalten des exception handlings etc).

    ist-zustand ist dass ich keine 4 LIBs mehr brauche, sondern nur noch 1.
    allerdings weiss ich noch nicht wieso ich pro VC-version ne eigene LIB kompilieren muss. liegt dass daran dass sich Kernel32.lib und User32.lib zwischen den versionen unterscheiden koennen?


  • Mod

    Klar weil das nur eine Link-Lib ist.
    Wenn also Deine DLL ein "braves" Interface hat (PODs, kene Allokationen über Module hinweg), dann benötigst Du immer nur 1 Lib und die DLL.

    BTW: Manchmal ist es nett dem Kunden auch eine Debug Version zur Verfügung zu stellen, die einige extra Checks hat.



  • loki1985 schrieb:

    ist-zustand ist dass ich keine 4 LIBs mehr brauche, sondern nur noch 1.
    allerdings weiss ich noch nicht wieso ich pro VC-version ne eigene LIB kompilieren muss. liegt dass daran dass sich Kernel32.lib und User32.lib zwischen den versionen unterscheiden koennen?

    Nö, aber die CRT.
    Wenn du z.B. irgendwo statische Objekte hast, die initialisiert werden möchten, dann ist das CRT-abhängig.

    Wenn deine LIB überhaupt keine CRT-Funktionen mehr benötigt, dann hast du mMn. gewonnen, dann sollte eine LIB für alle MSVC Versionen reichen. (Bzw. eine für x86 und eine für AMD64).

    Wenn du den Code nur gegen die Kunden deiner Kunden schützen musst, könntest du aber auch einfach die .h und .c Files für deine LIB mit ausliefern. Dann kann sich jeder Kunde bei bedarf eine passende LIB bauen, oder die Files gleich direkt in sein Projekt einbinden.

    Das würde dann u.U. auch das reverse-engineering des Kunden-Programms erschweren. Nämlich dann, wenn deine Lib viel in Inline-Funktionen macht und/oder der Kunde LTCG aufdreht.


Anmelden zum Antworten