{"id":46,"date":"2007-03-22T18:46:39","date_gmt":"2007-03-22T17:46:39","guid":{"rendered":"http:\/\/blog.m-ri.de\/index.php\/2007\/03\/22\/warum-man-seine-libraries-mit-_crt_noforce_manifest-erzeugen-sollte\/"},"modified":"2007-03-22T18:47:18","modified_gmt":"2007-03-22T17:47:18","slug":"warum-man-seine-libraries-mit-_crt_noforce_manifest-erzeugen-sollte","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2007\/03\/22\/warum-man-seine-libraries-mit-_crt_noforce_manifest-erzeugen-sollte\/","title":{"rendered":"Warum man seine Libraries mit _CRT_NOFORCE_MANIFEST erzeugen sollte"},"content":{"rendered":"<p>Seit VC 2005 wird die DLL-Version CRT ja grunds\u00e4tzlich \u00fcber ein Manifest geladen. Erzeuge ich Code, der die CRT verwendet, dann wird automatisch ein <em>#pragma comment(linker,&#8220;\/manifestdependency:..&#8220;)<\/em> Eintrag erzeugt. Den entsprechenden Code dazu findet man in der _crtdefs.h Datei des entsprechenden Include-Pfades.<\/p>\n<p>Dieser Manifest Eintrag wird sp\u00e4ter vom <em>Manifest Tool (MT.EXE)<\/em> gesammelt und im Manifest der Applikation oder der DLL verbaut.<\/p>\n<p>Gesetzt den Fall ich habe Library erzeugt, die auch die DLL-Version der CRT verwendet, dann wird automatisch die entsprechende Version der CRT im Manifest hinterlegt. D.h. bei VS 2005 RTM die CRT Version 8.0.50727.42 und bei SP1 die CRT Version 8.0.50727.762<\/p>\n<p>Wird nun f\u00fcr ein Projekt eine Library erzeugt mit einem VS 2005 RTM, und evtl. diese LIB lange nicht ver\u00e4ndert und dann diese Library in einem Programm verwendet, dass mit VS 2005 SP1 erzeugt wird, dann werden beide CRT Versionen im Manifest eingetragen!<br \/>\nDer Lader ist zwar intelligent und l\u00e4dt die letzte DLL (SP1). Aber undurchsichtig wird es in jedem Fall.<br \/>\nVor allem wenn man wirklich mit evtl. einer \u00e4lteren Version ausliefern m\u00f6chte und SP1 auf der Ziel-Maschine nicht installiert ist.<\/p>\n<p>Ich habe noch nicht genau herausbekommen wie entschieden wird welches der Manifesteintrag ist, der letzten Endes z\u00e4hlt. Scheinbar macht es auch nichts wenn, man die Version der CRT Versionen falsch angibt. Es wird dann die CRT mit der n\u00e4chst h\u00f6heren CRT geladen&#8230; (aber dazu muss ich noch etwas experimentieren)&#8230;<\/p>\n<p>Dieses Verhalten ist gravierend unterschiedlich zu allen Vorg\u00e4ngerversionen von VC. Wie bisher h\u00e4lt Microsoft das Versprechen der bin\u00e4ren Kompatibilit\u00e4t. Theoretisch m\u00fcsste auch die mit RTM erzeugte LIB sofort funktionieren. Auch der Linker wird diese LIB sofort mit der entsprechenden <em>MSVCR80(D).DLL<\/em> verbinden. Nur hat er eben nicht das letzte Wort bei den Manifesten.<\/p>\n<p>Man kann das ganze verhindern, indem man <em>_CRT_NOFORCE_MANIFEST<\/em> bevor die CRT Dateien inkludiert werden (am Besten in der stdafx.h oder in den Projekteinstellungen).<br \/>\nIn diesem Fall wird kein #pragma, dass f\u00fcr den Manifest Eintrag verantwortlich ist, erzeugt.<br \/>\nDer Effekt ist dann wie gewollt, dass nur das eigentliche Projekt, dass dann das Executable erzeugt Einfluss auf die Ausgabe des Manifestes hat. Man kann also dann auch eine Lib-Datei mit VS-2005 SP1 erzeugen und mit einem VS-2005 RTM linken. Das Manifest wurde durch diese Lib dann nicht beeinflusst und so soll es IMHO sein.<\/p>\n<p><strong>Aber aufgepasst:<\/strong><br \/>\nSeit VS-2005 muss in jedem Fall auf <strong>noch <\/strong>eine strenge Trennung der Release und Debug Versionen achten. Wenn nun kein Manifest mehr zum Beispiel in einer Release-Lib erzeugt wird, weil _CRT_NOFORCE_MANIFEST verwendet wird, nun aber diese Release Lib in ein Debug Projekt eingebunden wird.\u00a0 Dann wird das Executable implizit mit der MSVCR80.DLL gebunden, aber diese DLL kann nur \u00fcber ein Manifest geladen werden. Das ist aber nicht vorhanden. Resultat ist das was in diesem Beitrag beschrieben steht: <a href=\"http:\/\/blog.m-ri.de\/index.php\/2007\/03\/20\/manifest-hoelle-msvcr80dll-nicht-gefunden\/\" title=\"Manifest-H\u00f6lle \">Manifest-H\u00f6lle &#8222;\u2026MSVCR80.dll nicht gefunden\u2026&#8220;<\/a>\u00a0(siehe Nachtrag)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Seit VC 2005 wird die DLL-Version CRT ja grunds\u00e4tzlich \u00fcber ein Manifest geladen. Erzeuge ich Code, der die CRT verwendet, dann wird automatisch ein #pragma comment(linker,&#8220;\/manifestdependency:..&#8220;) Eintrag erzeugt. Den entsprechenden Code dazu findet man in der _crtdefs.h Datei des entsprechenden Include-Pfades. Dieser Manifest Eintrag wird sp\u00e4ter vom Manifest Tool (MT.EXE) gesammelt und im Manifest der &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2007\/03\/22\/warum-man-seine-libraries-mit-_crt_noforce_manifest-erzeugen-sollte\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eWarum man seine Libraries mit _CRT_NOFORCE_MANIFEST erzeugen sollte\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[19,3],"tags":[370,360,69],"class_list":["post-46","post","type-post","status-publish","format-standard","hentry","category-crt","category-programmieren","tag-c","tag-crt","tag-manifest"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/46","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=46"}],"version-history":[{"count":0,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/46\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=46"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=46"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=46"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}