Question

Désolé pour le long post qui suit.

Je sais que ce n'est pas une bonne idée de mélanger les statiquement liés et liés dynamiquement C et C ++ runtimes fourni par Microsoft. Notre application au travail les mélange déjà malheureusement et nous avons essayé de résoudre ce problème. Pour diverses raisons (parmi lesquelles MSI manque de familiarité avec le fait que nous utilisons NSIS qui ne peut-être supporte pas bien MSMs, le manque de temps et de ressources) nous avons décidé de relier les tubes cathodiques statiquement au lieu de façon dynamique. Je sais que les raisons pour lesquelles ce n'est pas une bonne idée, mais il était notre choix pour l'instant.


Notre code est principalement C ++ standard complétée par un certain nombre d'autres bibliothèques open source.

La structure de l'application est:. Divers modules qui donnent lieu à des bibliothèques statiques qui sont eux-mêmes reliés entre eux pour créer diverses choses parmi lesquelles un exécutable qui nous donne des problèmes

Dans la version que nous construisons tous notre avec le code / MT. Pour certaines des bibliothèques open source, nous avons utilisé les binaires précompilés et certains d'entre eux étaient dll précompilés avec / MD qui nous a fait mélanger les runtimes. Donc, nous nous recompilé ceux avec / MT et les a fait le résultat dans les bibliothèques statiques non dlls. Cette conversion ne se fait pas pour chaque bibliothèque, donc nous créer des liaisons avec des DLLs qui utilisent / MD.


Le résultat est maintenant que depends.exe toutes nos affaires sauf un exécutable ne pas directement dépendent msvcr80.dll ou msvcp80.dll. Par ne dépend pas directement Je veux dire que msvcr80.dll est pas un enfant de la racine de l'arbre montré par depends.exe. Parfois, nous ne trouvons msvcr80.dll entrané par une de la bibliothèque dll mais c'est des niveaux plus profonds dans l'arborescence.

Comment puis-je savoir pourquoi est-msvcr80.dll au premier niveau pour que l'un exécutable embêtant? Ce qui rend ce lien exécutable directement à msvcr80.dll?

L'une des raisons pourrait peut-être que nous associons statiquement à la bibliothèque A qui relie les usages / MD afin qu'il relie dynamiquement avec le CRT. Ainsi, le code dans la bibliothèque A se termine dans notre exécutable afin que nos liens exécutables avec msvcr80.dll. Mais comment puis-je savoir que l'une des bibliothèques fait ça?


Ce que j'ai essayé jusqu'à présent:

  • charger les fichiers .lib liés statiquement dans depends.exe -> ne fonctionne pas depuis depends.exe attend un exécutable ou une bibliothèque dll non statique
  • utilisation Dumpbin.exe / les fichiers de directives sur les .lib liés statiquement -> aucun d'entre eux ont montré msvcrt80.dll (alors que dans Debug, où nous essayons d'utiliser / MDd pour tout, ils ont fait msvcrt80d.dll show qui me fait penser la méthode est bonne et il prouve que toutes les bibliothèques open source liés statiquement sont correctement compilées avec / MT)
  • utilisez le / VERBOSE: LIB drapeau linker -> il a montré qu'en effet, il est tire dans msvcrt.lib qui est la bibliothèque d'importation pour msvcr80.dll donc nous sommes en difficulté, mais il n'a pas dit pourquoi il fait ça
  • utilisez le / VERBOSE drapeau linker + dans Visual Studio: Dépendances supplémentaires libcmt.lib + Ignorer toutes les bibliothèques par défaut OUI + Ignorer la bibliothèque spécifique: msvcrt.lib dans une tentative désespérée de faire msvcrt.lib aller ou voir qui tire ce . Le résultat me déconcerté:
    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)

Pour autant que je comprends, dans typinfo.obj libcmt.lib fait référence à un symbole, il recherche dans msvcrt.lib et après qu'il trouve dans ti_inst.obj il renvoie une erreur qu'il est défini deux fois. Mais cela n'a pas de sens. Si libcmt.lib a déjà le symbole pourquoi est-il finir par chercher dans msvcrt.lib et donc apporter msvcr80.dll dans mon exécutable? Et plus généralement, pourquoi la recherche de la bibliothèque statique pour les symboles dans la bibliothèque d'importation dynamique? Pourquoi l'éditeur de liens regarde même msvcrt.lib si je l'ai dans la bibliothèque Ignorer spécifique?

Merci pour votre patience: -.)

Était-ce utile?

La solution

J'ai la solution à mon problème. Ce fut une erreur stupide, il reste des temps anciens probablement.

msvcrt.lib a été explicitement mentionnée par nous dans la zone Dépendances supplémentaires :-( donc bien sûr, il a fait la dll une dépendance. Et à cause de toutes les bibliothèques open source cette boîte a beaucoup de texte pour que nous ne l'avons pas remarquer. Et pour être honnête, nous ne pensions même pas de regarder cette boîte avec soin, car nous ne pensions pas qu'il pourrait y avoir une telle erreur grossière dans nos projets.

Autres conseils

Ouvrez votre exécutable avec depends.exe et exécuter le profileur intégré dans depends. Je crois que ce consignera pourquoi tous vos dll sont chargés, et d'où ils sont chargés. Voir l'option "appels de fonction Log LoadLibrary".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top