2009-02-06 11 views
12

Estoy intentando construir una biblioteca estática C/C++ usando visual studio 2005. Como la selección de la biblioteca de tiempo de ejecución es una opción de compilación, me veo forzado a crear cuatro variaciones de mi biblioteca, una para cada variación de la biblioteca de tiempo de ejecución :¿Por qué la biblioteca de tiempo de ejecución es una opción de compilación en lugar de una opción de enlazador?

  • /MT - biblioteca de ejecución estática
  • /MD - biblioteca de tiempo de ejecución DLL
  • /MTd - depuración en tiempo de ejecución estática biblioteca
  • /MDd - depuración DLL de tiempo de ejecución biblioteca

Estas son opciones de compilador, no opciones de enlazador. Viniendo de un fondo de Linux, esto parece extraño. ¿Las diferentes bibliotecas de tiempo de ejecución tienen diferentes convenciones de llamadas o algo así? ¿Por qué no se pueden resolver las diferentes bibliotecas de tiempo de ejecución en tiempo de enlace, es decir, cuando enlace la aplicación que utiliza mi biblioteca estática?

+0

Si bien parece que hay buenas razones para esto en las respuestas, estoy de acuerdo con usted. Siempre termino buscando esta configuración en el lugar equivocado. Lo mismo con la configuración de los encabezados precompilados: tiene su propia categoría en lugar de ser algo en la sección Preprocesador. –

Respuesta

7

Un efecto secundario de las definiciones C preprocesador como _DLL y _DEBUG que Zdan mencionarse:

Algunas estructuras de datos (tales como contenedores STL y iteradores) puede ser de tamaño diferente en el tiempo de ejecución de depuración, posiblemente debido a características tales como _HAS_ITERATOR_DEBUGGING y _SECURE_SCL. Debe compilar su código con structure definitions that are binary-compatible with the library you're linking to.

Si se mezclan y ficheros objeto partido que fueron compilados contra diferentes bibliotecas de ejecución, recibirá advertencias de vinculador como las siguientes:

warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs 
0

Creo que la razón detrás de esto es que el código SEH (controlador de excepción estructurado) se generará de forma diferente según la biblioteca de tiempo de ejecución con la que se vincule.

1

Si ignora el tiempo de ejecución estático, obtiene las mismas opciones que Linux.

Sé que el tiempo de ejecución estático puede ser útil pero en realidad nunca lo he necesitado. También conduce a problemas potenciales relacionados con la asignación/desasignación de memoria y, como resultado, me resulta más fácil simplemente utilizar el tiempo de ejecución de DLL.

Tener versión Release/Debug es la misma que Linux/Unix.
Aunque por eficiencias, me explico que también puedo crear un solo hilo y versiones de múltiples hilos de bibliotecas.

8

Estas opciones pueden agregar definiciones (__DLL y __DEBUG por ejemplo) que se utilizan en los archivos de encabezado de la biblioteca de tiempo de ejecución. Una cosa común que hacer es agregar __declspec (dllimport) a las declaraciones de funciones cuando se vincula dinámicamente.

El compilador también parece utilizar estos para ayudar al vinculador a vincular a las bibliotecas correctas. Esto se explica en el MSDN.

3

El compilador necesita saber si está generando un código de subproceso único o multiproceso. Por defecto, el compilador genera código de seguridad de subprocesos (multiproceso). Tiene que indicar si desea un código de subproceso único. Si cambia el valor predeterminado, el compilador cambia la biblioteca de tiempo de ejecución predeterminada (siempre puede anular esto en las opciones del comando del enlazador, solo asegúrese de que la biblioteca que elija tenga el mismo código). estructura como sus archivos objeto: DLL de subproceso único estático, multi-threaded o multi-threaded). Tenga en cuenta que no hay una opción de DLL de subproceso único (por definición, la DLL de la biblioteca en tiempo de ejecución se habrá creado como segura para subprocesos, ya que varias aplicaciones la comparten).

+1

También ya no existe un tiempo de ejecución estático de subproceso único (no estoy seguro de si esto comenzó en VC2005 o VC2008). –

0

No es diferente código de máquina generado para DLL y las bibliotecas estáticas.

Y en Linux tiene que hacer lo mismo, la bandera del compilador se llama -fPIC si desea construir una biblioteca compartida. De lo contrario, en AMD64 y SPARC (y tal vez otros) se bloqueará. En la arquitectura i386, el enlazador es lo suficientemente inteligente y no comparte la biblioteca en la memoria para que no se cuelgue.

Cuestiones relacionadas