CRT vs 3rd party libraries [GELÖST]

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
ponx
Establishment
Beiträge: 217
Registriert: 04.05.2008, 12:52
Echter Name: Andy Ponx
Wohnort: Hamburg
Kontaktdaten:

CRT vs 3rd party libraries [GELÖST]

Beitrag von ponx »

hallo Leute,
hilfe hilfe ! ich biete eine Library als dll an, die jetzt jemand benutzen will, und zwar nach Möglichkeit ohne die CRTs von Visual Studio (2010) mitzuliefern. Jetzt wird's für mich ziemlich hässlich, weil ich wiederum noch zwei andere Libraries (boost und die google protocol buffers) und auch DirectX benutze. Wenn ich mal probeweise in meinem Projekt die zu verwendende Runtime Library von "Multi-threaded DLL" auf "Multi-threaded (/MT)" stelle, kriege ich jede Menge linker-errors wegen doppelt definierter Funktionen. Ich hab versucht mich im Netz schlau zu machen und bin hier gelandet: http://www.codeproject.com/KB/cpp/libraries1.aspx
Da wird ein Vorgang beschrieben, wie man seine eigenen CRTs bauen kann/muss. Führt da wirklich kein Weg dran vorbei, oder gibt's dazu vielleicht eine Alternative ? Zumal meine beiden verwendeten third-party libraries open source sind.

Ich hab jetzt schon überlegt ob ich die ganze Library nicht einfach als statische .lib anbiete. Ich hab's gebaut und es sind dann satte 46 MB schon für die release-version :/ Dazu noch eine Verständnisfrage: Mich wundert, dass ich keine Linker-Errors bekomme, sobald ich das Projekt als statische .lib anbiete. Es scheint bei allen verwendeten Projekten dann fast egal zu sein, was ich als Runtime Library eingestellt habe. Er baut immer erfolgreich, und nur die Größe meiner lib schwankt um ca 3 MB. Wieso gibt's da keine Konflikte, und was macht meine .lib dann so groß ?

Experten gesucht... vielen Dank Leute
Zuletzt geändert von ponx am 18.01.2012, 15:39, insgesamt 1-mal geändert.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: CRT vs 3rd party libraries

Beitrag von Sternmull »

Die Linkerfehler bekommst du höchst wahrscheinlich weil die libs die du verwendest nicht mit der gleichen Version der CRT erstellt wurden wie deine DLL. Wenn alle die gleiche Version verwenden gibts da auch keine Konflikte. Eine eigene CRT braucht man sich dafür nicht bauen.
Die CRT und Boost lassen sich statisch linken, für Protocol-Buffers scheint das auch zu gehen. Nur DirectX wird dann noch auf dem Zielsystem vorausgesetzt.

Also: Alle libs in einer statischen version bauen die die statische CRT verwendet.

Zur Verständnisfrage: Wenn mich nicht alles täuscht werden die Konflikte (zwischen verschiedenen CRT-Versionen gegen die gleichzeitig gelinkt werden soll) erst gemeldet wenn man ein Binary (DLL oder EXE) baut. D.h. wenn du die statische lib dann in einer EXE verwendest die auch wieder verschiedene CRTs linkt hast du das gleiche Problem wie vorher.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: CRT vs 3rd party libraries

Beitrag von Schrompf »

Aaaalso: wenn Du Deine DLL als MultiThreaded baust, also die CRT statisch linkst, dann musst Du alle Libs ebenso damit neubauen. Wenn eine der Libs, gegen die Deine DLL linkt, MultiThreaded-DLL (oder irgendwas anderes) nutzt, meckert der Linker, weil die Funktionen zwar identische Signaturen, aber nicht identischen Code haben und er sie deswegen nicht zusammenfalten kann. Dieses "Zusammenfalten" (englisch "Folding"... seine Worterfindung, nicht meine) passiert auch bei ganz banalen Sachen wie z.B. wenn Du eine Lib aus einem älteren Visual Studio in ein aktuelles Projekt linken willst. Der Code von praktisch allen Funktionen weicht dann ein bisschen von dem Code in Deinem Projekt ab, weswegen Du Millionen an Linkerfehlern selbst in std::string und Konsorten kriegst.

Lösung hierfür also: die Libs, gegen die Deine DLL linkt, ebenso neubauen mit der selben CRT wie Deine DLL.

Größe der statischen Lib: scheißegal. Im Ernst. Der Linker hat hier die Möglichkeit, alle nichtbenutzen Funktion rauszuwerfen und alle CRT-Funktionen (und auch alle anderen gemeinsamen Funktionen, siehe oben) beim Linken zusammenzulegen, weswegen die Ziel-Exe bei weitem nicht so groß wird, wie die Größe der Linker-Lib vermuten ließe. Natürlich wird die Lib etwas größer, wenn Du die CRT statisch mit reinlinkst. Der da hinzugefügte Code wird aber mit dem (ebenso statisch CRT-gelinkten) Code in Deiner Exe zusammengelegt, wenn Du die Lib statisch linkst. Ich behaupte also, dass Exe + statisch gelinkte Lib + statisch gelinkte Runtime zusammen kleiner sind als Exe mit dynamisch gelinkter CRT + DLL mit dynamisch gelinkter CRT + CRT-DLL.

Was die ausbleibenden Konflikte bei statisch gelinkter Lib angeht: da bin ich überfragt. Eigentlich müsste es ebenso einen Reigen aus Linkerfehlern geben, wenn Deine Lib eine andere CRT als die Haupt-Exe nutzt. Vielleicht kracht das aber auch erst zur Laufzeit :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
jumphigh
Beiträge: 19
Registriert: 30.06.2004, 13:41
Kontaktdaten:

Re: CRT vs 3rd party libraries

Beitrag von jumphigh »

Wer in einer Allzweck-DLL C++-Objekte im Interface benutzt, macht etwas verkehrt! Im Prinzip musst du dann deine DLL in zig Versionen, nämlich in jeder unterstützten Toolchain jeder Version inkl. aller abhängigen Bibliotheken bauen und verteilen. Da das mit ziemlicher Sicherheit niemals funktionieren wird, sollte man sich auf POD und C-Interfaces beschränken oder COM als allgemeinverbindlichen Standard für Objekte nutzen.

Wenn du Boost etc. nur *innerhalb* deiner DLL nutzt, dann würde ich ganz einfach statisch binden, so dass deine Clients nur deine DLL benötigen. Dann sollte es für eine C++-DLL reichen, mit den gewünschten Toolchains zu bauen, z.B. eine Version mit VS 2010, eine mit GCC x.y.z. Deine Clients wären dann aber auch auf diese Toolchains festgelegt. Oder aber du lieferst den Quellcode aus und jeder muss sich die richtige Version für seine Umgebung bauen. Ich würde z.B. nie eine DLL kaufen, bei der die Sourcen nicht mitgeliefert werden. Ohne steht man bei Abkündigung des Produktes schnell mal mit einem unwartbaren Monster da.

MfG
Andreas
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: CRT vs 3rd party libraries

Beitrag von Sternmull »

jumphigh hat geschrieben:Wer in einer Allzweck-DLL C++-Objekte im Interface benutzt, macht etwas verkehrt! Im Prinzip musst du dann deine DLL in zig Versionen, nämlich in jeder unterstützten Toolchain jeder Version inkl. aller abhängigen Bibliotheken bauen und verteilen. Da das mit ziemlicher Sicherheit niemals funktionieren wird, sollte man sich auf POD und C-Interfaces beschränken oder COM als allgemeinverbindlichen Standard für Objekte nutzen.
Jep. Und auch gleich noch eine Version für alle möglichen Konfigurationen von Präprozessordefinitionen und Varianten von Standardbibliotheken.
jumphigh hat geschrieben: Wenn du Boost etc. nur *innerhalb* deiner DLL nutzt, dann würde ich ganz einfach statisch binden, so dass deine Clients nur deine DLL benötigen. Dann sollte es für eine C++-DLL reichen, mit den gewünschten Toolchains zu bauen, z.B. eine Version mit VS 2010, eine mit GCC x.y.z. Deine Clients wären dann aber auch auf diese Toolchains festgelegt.
Wenn er das so macht (alles statisch in die DLL linken und Interface per C, COM, oder sonstwas mit wohldefinierter ABI), dann braucht er keine spezielle Versionen der DLL pro Toolchains. Das ist ja grad der Witz an der Sache.
Benutzeravatar
ponx
Establishment
Beiträge: 217
Registriert: 04.05.2008, 12:52
Echter Name: Andy Ponx
Wohnort: Hamburg
Kontaktdaten:

Re: CRT vs 3rd party libraries

Beitrag von ponx »

Leute vielen Dank, das hat schon enorm geholfen !
Den Einwand mit dem C++-Interface hab ich noch nicht ganz verstanden. Mir war klar, dass ich am besten ein reines C-Interface anbiete, um keinen Ärger mit ABI-Inkompatibilitäten zu bekommen. Aber ich hatte mir in Verbindung mit der CRT etc. da noch keine Gedanken gemacht, bis jetzt ging's ja immer (kein Wunder, wenn ich der einzige Anwender bin :) ). Ich binde im Moment in meiner Interface-Klasse auch den precompiled-Header ein, in dem ich alles mögliche include, was man da halt so einbindet...lasst mich raten, schlechte Idee ? ich tu's raus...
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: CRT vs 3rd party libraries

Beitrag von Schrompf »

Wenn Du eine Lib als DLL rausgeben willst, solltest Du dringend zwischen Schnittstelle und Implementation trennen. Mach ein Include-Verzeichnis auf, in dem Du nur Header reintust, die die reine Schnittstelle der Lib beschreiben. Ein Nutzer Deiner DLL muss damit ja auch arbeiten können, ohne alle internen Header der Implementation zu haben. Das zwingt nebenbei auch zu einem sauberen Design, weil Dir damit offensichtlich gemacht wird, was für Typen außen alles gebraucht werden.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: CRT vs 3rd party libraries

Beitrag von Sternmull »

Wenn du wirklich eine DLL mit C++ API bastelst, dann solltest du dir angucken wie andere das machen. Z.b. dürften die "Policies/Binary Compatibility Issues With C++" von Qt ganz brauchbar sein.
jumphigh
Beiträge: 19
Registriert: 30.06.2004, 13:41
Kontaktdaten:

Re: CRT vs 3rd party libraries

Beitrag von jumphigh »

Sternmull hat geschrieben:Wenn er das so macht (alles statisch in die DLL linken und Interface per C, COM, oder sonstwas mit wohldefinierter ABI), dann braucht er keine spezielle Versionen der DLL pro Toolchains. Das ist ja grad der Witz an der Sache.
Das ist doch klar, handelt es sich in diesem Fall ja auch nicht um eine "C++-DLL". Es ging mir bei diesem Punkt darum, dass man natürlich auch eine C++-DLL bauen kann, wenn man sich auf eine spezielle Tool-Chain festlegt. Dies gilt im Übrigen nicht nur für DLLs, sonder auch für statische Libs, auch diese sind auf eine Umgebung festgelegt.

Ich z.B. habe meine eigene Win-Lib, in der ich Boost verwende und C++-Objekte wie String nach Außen gebe. Das funktioniert, weil ich für jede Toolchain (VS 2005/08/10 MT/MTd) sowohl meine Lib inkl. Boost übersetze und mittels Präprozessor und #pragma lib die richtige Lib automatisch linken lasse.

MfG
Andreas
Benutzeravatar
ponx
Establishment
Beiträge: 217
Registriert: 04.05.2008, 12:52
Echter Name: Andy Ponx
Wohnort: Hamburg
Kontaktdaten:

Re: CRT vs 3rd party libraries

Beitrag von ponx »

Jetzt klappt alles ! :D vielen Dank nochmal an euch alle ! hab wieder einiges gelernt
Antworten