Pregunta

Lo sentimos por el largo post que sigue.

Yo sé que no es una buena idea mezclar el C enlazado estáticamente y dinámicamente vinculados y tiempos de ejecución de C ++ suministrado por Microsoft. Nuestra aplicación en el trabajo ya los mezcla desgracia y hemos estado tratando de arreglar eso. Por diversas razones (entre los que no está familiarizado con MSI, el hecho de que usamos NSIS, que tal vez no sea compatible con los HSH, así, la falta de tiempo y recursos) decidimos unir los tubos de rayos catódicos de forma estática en lugar de forma dinámica. Conozco las razones por las que esto no es una buena idea, pero fue nuestra elección por ahora.


Nuestro código es principalmente C ++ estándar complementada con un buen montón de otras bibliotecas de código abierto.

La estructura de la aplicación es:. Diversos módulos que dan lugar a las bibliotecas estáticas que a su vez están unidos entre sí para crear varias cosas entre las cuales un ejecutable que nos está dando problemas

En la versión que construir todos nuestro código con / MT. Para algunas de las bibliotecas de código abierto se utilizó binarios precompilados y algunos de ellos eran DLL precompilado con / MD que nos hizo mezclamos los tiempos de ejecución. Por lo que vuelve a compilar los mismos con / MT y las han resultado en las bibliotecas estáticas no dlls. Esta conversión no se realiza para cada biblioteca, por lo que todavía enlazar con algunos archivos DLL que utilizan / MD.


El resultado es que ahora en depends.exe todas nuestras cosas excepto uno ejecutable no directamente depende de msvcr80.dll o msvcp80.dll. Por no depende directamente quiero decir que msvcr80.dll no es un hijo de la raíz del árbol que se muestra por depends.exe. A veces que sí encontramos msvcr80.dll empujados por una de las DLL de la biblioteca, pero que de algún nivel más profundo en el árbol.

¿Cómo puedo saber qué es msvcr80.dll en el primer nivel para que un ejecutable molestos? Lo que hace que enlazan ejecutable directamente a Msvcr80.dll?

Una de las razones podría ser tal vez de que enlace estáticamente a la biblioteca A, que une usos / MD por lo que enlaza dinámicamente con el CRT. Así que el código en la biblioteca Un termina en nuestro ejecutable para que nuestros enlaces ejecutables con msvcr80.dll. Pero, ¿cómo puedo saber cuál de las bibliotecas hace eso?


Lo he intentado hasta ahora:

  • cargar los archivos enlazados estáticamente .lib en depends.exe -> no funciona desde depends.exe espera un ejecutable o DLL no una biblioteca estática
  • Uso Dumpbin.exe / directivas sobre los archivos enlazados estáticamente lib -> ninguno de ellos mostraron msvcrt80.dll (mientras que en la depuración, donde tratamos de usar / MDd para todo, sí mostraron msvcrt80d.dll que me hace pensar el método es bueno y demuestra que todas las bibliotecas de código abierto enlazados estáticamente se compilan correctamente con / MT)
  • utilizar el VERBOSE / bandera enlazador LIB -> mostró que, efectivamente, se está tirando en msvcrt.lib que es la biblioteca de importación para msvcr80.dll por lo que estamos en problemas pero no dijo por qué está haciendo eso
  • usar la bandera enlazador / VERBOSE + en Visual Studio: Dependencias adicionales LIBCMT.LIB + Ignorar todas las bibliotecas predeterminadas SI + Ignorar biblioteca específica: msvcrt.lib en un intento desesperado para hacer msvcrt.lib desaparece o ver quién tira de ella se . El resultado perplejo mí:
    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)

Por lo que yo entiendo, typinfo.obj en LIBCMT.LIB hace referencia a un símbolo, busca en msvcrt.lib y después de que encuentra en ti_inst.obj que arroja un error que se define en dos ocasiones. Pero esto no tiene sentido. Si LIBCMT.LIB ya tiene el símbolo ¿por qué terminar en busca de ella en msvcrt.lib y por lo tanto trayendo msvcr80.dll en mi ejecutable? Y más en general, ¿por qué la búsqueda biblioteca estática para los símbolos en la biblioteca de importación dinámica? ¿Por qué el enlazador incluso mirar msvcrt.lib si lo tengo en la biblioteca específica haga caso?

Gracias por su paciencia: -).

¿Fue útil?

Solución

Tengo la solución a mi problema. Fue un error estúpido dejado allí desde la antigüedad probablemente.

msvcrt.lib se ha mencionado explícitamente por nosotros en el cuadro Dependencias adicionales :-( así que por supuesto hizo el DLL una dependencia. Y a causa de todas las bibliotecas de código abierto esa caja tiene una gran cantidad de texto, de modo que no lo hicimos notarlo. Y para ser sincero, ni siquiera se nos ocurrió mirar esa caja con cuidado ya que no imaginamos que podría haber un error tan bruta en nuestros proyectos.

Otros consejos

Abra su ejecutable con depends.exe y ejecutar el perfilador integrado en depende. Creo que esto va a registrar qué se cargan todos sus dlls, y desde donde se cargan. Vea la opción "Registro de llamadas a funciones LoadLibrary".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top