2009-04-16 6 views
98

En Visual Studio, existen los indicadores de compilación/MD y/MT que le permiten elegir el tipo de biblioteca de tiempo de ejecución de C que desea.¿Debo compilar con/MD o/MT?

Entiendo la diferencia en la implementación, pero todavía no estoy seguro de cuál usar. ¿Cuáles son los pros/contras?

Una ventaja de/MD que he escuchado, es que esto permite a alguien para actualizar el tiempo de ejecución, (como tal vez parchear un problema de seguridad) y mi aplicación se beneficiará de esta actualización. Aunque para mí, esto casi parece una falta de características: ¡no quiero que la gente cambie mi tiempo de ejecución sin permitirme probar contra la nueva versión!

Algunas cosas que he tenido curiosidad por:

  • ¿Cómo afectaría esto a los tiempos de construcción? (presumiblemente/MT es un poco más lento?)
  • ¿Cuáles son las otras implicaciones?
  • ¿Cuál usa la mayoría de las personas?
+0

Más información y sugerencias se pueden encontrar en: http: // stackoverflow.com/questions/787216 – Weidenrinde

Respuesta

66

Al enlazar dinámicamente con/MD,

  • usted está expuesto a las actualizaciones del sistema (para bien o para mal),
  • su ejecutable puede ser más pequeña (ya que no tiene la biblioteca incrustado en él) y
  • Creo que, como mínimo, el segmento de código de una DLL se comparte entre todos los procesos que lo usan activamente (reduciendo la cantidad total de RAM consumida).

También encontré que en la práctica, cuando se trabaja con librerías binarias de terceros vinculadas estáticamente que se han creado con diferentes opciones de tiempo de ejecución,/MT en la aplicación principal tiende a causar conflictos mucho más a menudo que/MD (porque tendrá problemas si el tiempo de ejecución de C está vinculado estáticamente varias veces, especialmente si son versiones diferentes).

+10

El bit de actualizaciones del sistema se ve algo reducido por SxS. El EXE puede declarar qué versión de CRT quiere (quiere, no obtiene - las actualizaciones de seguridad pueden invalidar esto) – MSalters

+0

Esto significa que si compilo usando MD y mi programa depende de algún dll, el programa fallará si se ejecuta en una computadora donde la dependencia dll es inexistente? – gerrytan

+4

@gerrytan: Sí, deberá asegurarse de que las DLL adecuadas que se utilizan estén presentes en todas las computadoras que desean ejecutar el software. Las soluciones típicas para esto son hacer que el usuario instale el paquete MSVC redistribuible apropiado, o usar un instalador que haga todo el trabajo. –

14

Creo que el valor predeterminado para los proyectos creados a través de Visual Studio es/MD.

Si utiliza/MT, el ejecutable no dependerá de una DLL que está presente en el sistema de destino. Si está envolviendo esto en un instalador, probablemente no sea un problema y puede ir de cualquier manera.

Yo uso/MT yo mismo, por lo que puedo ignorar todo el lío DLL.

P.S. Como señala Mr. Fooz, es vital ser consecuente. Si está enlazando con otras bibliotecas, debe usar la misma opción que ellos. Si está utilizando una DLL de un tercero, es casi seguro que necesitará usar la versión DLL de la biblioteca en tiempo de ejecución.

4

de http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx:

/MT Define _MT por lo que las versiones multiproceso-específica de las rutinas de tiempo de ejecución se seleccionan del encabezado estándar (.h) archivos. Esta opción también hace que el compilador coloque el nombre de la biblioteca LIBCMT.lib en el archivo .obj para que el vinculador use LIBCMT.lib para resolver los símbolos externos. O bien/MT o/MD (o sus equivalentes de depuración/MTd o/MDd) son necesarios para crear programas multiproceso.

/MD Define _MT y _DLL para que las versiones de las rutinas de tiempo de ejecución tanto multithread como DLL estén seleccionadas de los archivos .h estándar. Esta opción también hace que el compilador coloque el nombre de la biblioteca MSVCRT.lib en el archivo .obj.

Las aplicaciones compiladas con esta opción están vinculadas estáticamente a MSVCRT.lib. Esta biblioteca proporciona una capa de código que permite al vinculador resolver referencias externas. El código de trabajo real está contenido en MSVCR71.DLL, que debe estar disponible en tiempo de ejecución para las aplicaciones vinculadas con MSVCRT.lib.

Cuando/MD se utiliza con _STATIC_CPPLIB definido (/ D_STATIC_CPPLIB) hará que la aplicación se vincule con la biblioteca multitoma estática estándar C++ (libcpmt.lib) en lugar de la versión dinámica (msvcprt.lib) mientras se enlaza dinámicamente a el CRT principal a través de msvcrt.lib.

Así que si estoy interpretando correctamente luego /MT enlaces estática y /MD enlaces dinámicamente.

9

Prefiero conectar estáticamente con/MT.

A pesar de que usted consigue un ejecutable más pequeño con/MD, todavía tiene que enviar un montón de DLL para asegurarse de que el usuario obtiene la versión correcta para el funcionamiento de su programa. Y al final su instalador va a ser MÁS GRANDE que cuando se vincula con/MT.

Lo que es aún peor, si elige colocar sus bibliotecas de tiempo de ejecución en el directorio de Windows, tarde o temprano el usuario va a instalar una nueva aplicación con diferentes bibliotecas y, con mala suerte, romperá su aplicación.

+3

Muy mala idea para "poner sus bibliotecas de tiempo de ejecución en el directorio de Windows". Puede romper otras aplicaciones tontas que hicieron lo mismo antes que usted. Use SxS y deje que el instalador lo maneje, o quédese con/MT. – MSalters

+1

Estoy totalmente de acuerdo en que es una mala idea. Algunas personas lo hacen, así que estaba describiendo por qué esta no es una buena idea. –

+0

@AdrianGrigore ¿por qué una nueva aplicación con diferentes bibliotecas causará un corte en su aplicación? Si usa/MD linkage, simplemente comenzaría a cargar las nuevas versiones de las bibliotecas ¿verdad? – rturrado

6

El problema que se ejecutará en con/MD es que la versión de destino de la CRT puede no estar en su máquina de los usuarios (especialmente si usted está utilizando la última versión de Visual Studio y el usuario tiene un sistema operativo anterior) .

En ese caso, usted tiene que encontrar la manera de obtener la versión de la derecha en su máquina.

26

Si está utilizando DLL entonces hay que ir por el CRT de enlace dinámico (/ MD).

Si utiliza el CRT dinámico para su .exe y todos los .dll, todos compartirán una única implementación del CRT, lo que significa que todos compartirán un solo montón de CRT y memoria asignada en un .exe/.dll puede ser liberado en otro.

Si usa el CRT estático para su .exe y todos los .dlls, todos obtendrán una copia separada del CRT, lo que significa que todos usarán su propio montón de CRT para que la memoria se libere en el mismo módulo en el que fue asignado. También sufrirá la saturación del código (varias copias de la CRT) y el exceso de sobrecarga en el tiempo de ejecución (cada montón asigna memoria desde el sistema operativo para hacer un seguimiento de su estado, y la sobrecarga puede ser notable).

1

Si usted está construyendo ejecutable que utiliza otros archivos DLL o bibliotecas que se prefiere la opción/MD porque de esa manera todos los componentes estarán compartiendo misma biblioteca. Por supuesto, esta opción debe coincidir con todos los módulos involucrados, es decir, dll/lib/exe.

Si el ejecutable no utiliza ningún lib o DLL que la llamada de su cualquiera. La diferencia no es demasiado ahora porque el aspecto de compartir no está en juego.

Así que tal vez puede iniciar la aplicación con/MT ya que no hay una razón convincente, pero cuando es hora de agregar una lib o dll, puede cambiarla a/MD con la de lib/dll, que es fácil.