2008-10-26 16 views
18

En los años 90, cuando comencé con MFC, solía vincular dinámicamente mis aplicaciones y enviaba las DLL de MFC pertinentes. Esto me causó algunos problemas (¡DLL infierno!) Y en su lugar cambié a enlaces estáticos, no solo para MFC, sino para CRT y ATL. Además de los archivos EXE más grandes, la vinculación estática nunca me ha causado ningún problema, ¿hay algún inconveniente que otras personas hayan encontrado? ¿Hay alguna buena razón para volver a visitar los enlaces dinámicos? Mis aplicaciones son principalmente STL/Boost hoy en día FWIW.Enlace estático o dinámico de CRT, MFC, ATL, etc.

Respuesta

17

hay algunas desventajas:

  • un tamaño más grande exe (especialmente si usted envía múltiples exe)
  • Problemas al utilizar otra DLL que se basan en o asumen la vinculación dinámica (por ejemplo: 3 ª parte de DLL que no se puede conseguir bibliotecas estáticas)
  • diferentes c-tiempos de ejecución entre los DLL con vinculación estática independiente (sin módulo cruz asignar/desasignar)
  • sin mantenimiento automático de los componentes compartidos (sin capacidad de tener actualizar tercero proveedor de módulos parte de su código para solucionar problemas sin recomp Iling y actualización de su aplicación)

Hacemos vinculación estática para nuestras aplicaciones de Windows, principalmente debido a que permite la implementación xcopy, que simplemente no es posible con la instalación o depender de SxS DLL de una manera que funciona, ya que el proceso y el mecanismo no está bien documentado o es fácilmente remotable. Si utiliza las DLL locales en el directorio de instalación, funcionará, pero no está bien soportado.La incapacidad de realizar fácilmente la instalación remota sin pasar por un MSI en el sistema remoto es la razón principal por la que no utilizamos enlaces dinámicos, pero (como usted señaló) hay muchos otros beneficios para los enlaces estáticos. Para cada uno hay pros y contras; con suerte, esto ayuda a enumerarlos.

+0

Se describe un enfoque posiblemente mejor (ensamblajes privados) en http://stackoverflow.com/questions/787216 – Weidenrinde

1

No, nada nuevo en ese frente. Déjalo de esa forma.

1

Definitivamente.

La asignación se realiza en un montón "estático". Dado que la asignación y la desasignación deben realizarse en el mismo montón, esto significa que si envía una biblioteca, debe tener cuidado de que el código del cliente no pueda llamar a "su" p = new LibClass() y eliminar ese objeto utilizando el delete p;.

Mi conclusión: cualquiera de las asignaciones de blindaje y desasignación del código de cliente, o vincular dinámicamente el CRT.

4

Mientras mantenga su uso limitado a ciertas bibliotecas y no use ninguna dll, entonces debería estar bien.

Desafortunadamente, hay algunas bibliotecas que no puede vincular estáticamente. El mejor ejemplo que tengo es OpenMP. Si aprovecha el soporte OpenMP de Visual Studio, deberá asegurarse de que el tiempo de ejecución esté instalado (en este caso vcomp.dll).

Si usas dll entonces no puedes pasar algunos elementos de ida y vuelta sin una gimnasia seria. Std :: cadenas vienen a la mente. Si su exe y dll están vinculados dinámicamente, entonces la asignación tiene lugar en el CRT. De lo contrario, su programa puede tratar de asignar la cadena en un lado y desasignarla en el otro. Siguen cosas malas ...

Dicho esto, sigo vinculando de forma estática los archivos exe y dll's. Reduce mucho la variabilidad en la instalación y considero que vale la pena las pocas limitaciones.

+1

Lo que sucede con la asignación de memoria no es correcto. Cuando utiliza DLL CRT, solo hay un CRT presente en la aplicación para que pueda asignar desde una DLL y desasignar en la otra, todo va al mismo montón porque es la misma CRT. –

+0

Es cierto, pero si el exe y el dll están vinculados estáticamente, entonces hay dos montones. ¿Derecha? Al menos esa ha sido mi experiencia. Tengo que decírtelo, poder pasar una std :: string de un lado a otro o un vector habría hecho mi vida mucho más fácil. –

+2

La solución al problema de std :: string no es waffling. O enlace estáticamente o enlace dinámicamente. Si tiene al menos un archivo DLL de C++, establezca un vínculo con el archivo DLL de CRT. – MSalters

2

Una buena característica del uso de dll es que si múltiples procesos cargan el mismo dll, su código puede ser compartido entre ellos. Esto puede ahorrar memoria y acortar los tiempos de carga para una aplicación que carga un dll que ya está siendo utilizado por otro programa.

+2

Eso puede ahorrar memoria del sistema por deduplicación de página, pero el espacio de dirección virtual de proceso individual se reduce: en lugar de que solo partes de una biblioteca se arrastren a un archivo ejecutable, tiene toda la biblioteca asignada al espacio de direcciones de proceso. Con múltiples DLL mapeadas y con ASLR, el espacio de direcciones virtuales del proceso se fragmenta, lo que al menos para las aplicaciones de 32 bits reduce considerablemente el tamaño del bloque de memoria contiguo que se puede asignar. –

18

La mayoría de las respuestas que escucho sobre esto involucran compartir su dll con otros programas, o tener esos dll's actualizados sin la necesidad de parchear su software.

Francamente, considero que se trata de inconvenientes, no de ventajas. Cuando se actualiza un dll de un tercero, puede cambiar lo suficiente como para romper su software. Y en estos días, el espacio en el disco duro no es tan precioso como lo era una vez, ¿500k adicionales en su ejecutable? ¿A quien le importa?

  • Estar 100% seguro de la versión de dll que está usando su software es algo bueno.
  • Estar 100% seguro de que el cliente no va a tener un dolor de cabeza de dependencia es algo bueno.

Los aspectos positivos son muy superiores a las desventajas en mi opinión

1

Hay algunas licencias de software, tales como LGPL que le obliguen a utilizar una DLL o distribuir su aplicación como ficheros objeto que el usuario puede vincular juntos. Si está utilizando una biblioteca de este tipo, es probable que desee utilizarlo como una DLL.

+0

Si tiene que usar una biblioteca de este tipo, puede pagar un rescate para establecer un enlace estático (en lugar de arrastrarlo por la DLL) – Navin

Cuestiones relacionadas