2009-04-24 16 views
17

He leído argumentos en ambos lados sobre si se debe vincular de forma estática o dinámica a la biblioteca C runtime en proyectos de Visual Studio, y aún no estoy del todo seguro de qué pensar.¿Debo vincular el tiempo de ejecución de Visual Studio C de forma estática o dinámica?

Mi proyecto extrae algunas bibliotecas de terceros (Python, HDF5, Trilinos y Microsoft MPI), cada una de las cuales debe compilarse con la misma biblioteca de tiempo de ejecución que mi último ejecutable (de lo contrario, no pueden vincularse). Al vincular estáticamente, cada una de estas bibliotecas contendrá una copia del tiempo de ejecución de C. Leí que esto puede causar problemas porque el ejecutable final contendrá varias copias del tiempo de ejecución, ninguna de las cuales puede interactuar entre sí. Pero, ¿no se quejaría el vinculador si los mismos símbolos se definieran de forma múltiple?

Me gustaría evitar "DLL Hell" pero me preocupan los errores insidiosos que pueden surgir al vincular estáticamente en varias copias del tiempo de ejecución. ¿Estoy leyendo cosas mal?

Además, estoy usando Visual Studio 2005 y he leído que el tiempo de ejecución del Service Pack 1 no es compatible con versiones anteriores. ¿Esto significa que una aplicación creada sin SP1 no se ejecutará en una máquina que tenga los dlls SP1, incluso si tienen el mismo nombre (por ejemplo, msvcr80.dll)?

Respuesta

23

La vinculación estática hinchará todos sus EXEs y DLL, y puede causar bloqueos (por ejemplo, si el código en una DLL llama a free() con un puntero asignado por malloc() en una DLL diferente).

Puede obtener lo mejor de ambos mundos vinculando dinámicamente e implementando las DLL de tiempo de ejecución como ensamblados privados. Esto simplemente significa poner una copia de un directorio con nombre especial que contenga las DLL de tiempo de ejecución y sus manifiestos al lado de su ejecutable.

Consulte la sección "Distribución de Visual C++ DLL de la biblioteca como asambleas privadas" en http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx para los detalles, pero básicamente su aplicación se ve así:

c:\Program Files\My App\MyApp.exe 
c:\Program Files\My App\MyLibrary.dll 
c:\Program Files\My App\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest 
c:\Program Files\My App\Microsoft.VC80.CRT\msvcr80.dll 

En cuanto a su última pregunta, sí, el equipo de destino necesita el las versiones correctas de las DLL de tiempo de ejecución funcionan, pero al implementarlas como ensamblados privados, usted garantiza eso.

Otra ventaja es que los usuarios que no son administradores pueden instalar su aplicación (no en Archivos de programa, sino en cualquier otro lugar): no necesitan permiso para escribir archivos en el área de WinSxS.

+0

Esta es la respuesta que estaba buscando. Parece que los ensamblajes privados son la solución más segura para mi problema. Me recuerda a los paquetes de Mac en que una aplicación se distribuye en una estructura de directorio fija. ¡Gracias! – user76293

+6

Pero los ensamblados privados no serán parcheados por Windows Update, ¿correcto? Por lo tanto, deberá mantener su copia de la biblioteca en tiempo de ejecución actualizada por su cuenta. Ver también http://blogs.msdn.com/larryosterman/archive/2004/04/29/123090.aspx –

+0

Nunca tuve esos ensamblajes privados funcionando si mi carpeta 'application' (Mi aplicación) contiene una mezcla de 32 bits y aplicaciones de 64 bits. No puede simplemente agregar algo como x32 o x64 al nombre de la carpeta del ensamblado, lo que significa que solo puede usar los ensamblajes privados si solo tiene aplicaciones de 32 bits o solo de 64 bits. – Patrick

0

Las bibliotecas estáticas no necesitan estar vinculadas estáticamente a otras bibliotecas estáticas. Solo necesita vincular todas las bibliotecas estáticas en su proyecto principal. De esta forma, el compilador no se quejará de múltiples símbolos.

+0

Para aclarar: no vinculo las bibliotecas entre sí, y no obtengo símbolos definidos de forma múltiple cuando enlazo mi ejecutable principal. Pero no estoy seguro de si hay varias copias del tiempo de ejecución de C en mi archivo ejecutable, que es lo que sucede cuando lo vinculan estáticamente (de acuerdo con mi interpretación de lo que he leído, lo cual puede ser incorrecto). – user76293

2

... Hacerlo estáticamente ... los intentos de arreglar DLL Hell no han funcionado tan bien ... solo agregue 200k adicionales a su instalación con el enlace estático.

+0

¿Alguna idea sobre las copias múltiples del tiempo de ejecución? Esa es mi verdadera pregunta. – user76293

+0

Habrá varias copias de un tiempo de ejecución flotando de todos modos. Para eso está la carpeta WinSxS (y ese es un intento de arreglar DLL Hell). Sin embargo, es confuso, por lo que empaquetar su propio tiempo de ejecución evitará tales problemas. – CookieOfFortune

11

La única vez que obtendrá varias copias del tiempo de ejecución es cuando vincula estáticamente una biblioteca a un archivo DLL; cada archivo DLL obtendrá una copia, al igual que el archivo ejecutable. Si son todas las bibliotecas estáticas y no las DLL, todas se vincularán entre sí y todas sus bibliotecas compartirán el mismo tiempo de ejecución.

Ese es el trabajo del enlazador.

Cuestiones relacionadas