2012-01-16 7 views
5

En mi empresa, recientemente cambiamos de VC9 a VC10.¿La mezcla de tiempos de ejecución es una solución viable?

Migramos nuestros proyectos, pero luego, la persona a cargo nos dijo que tendríamos que mantener algunos archivos DLL comunes de base compilados con VC9 en nuestras máquinas de producción durante algún tiempo.

Estas DLL hacen uso de estructuras personalizadas, algunas de las cuales contienen std::vector, std::map y así sucesivamente. Ahora, me llamó la atención que el tamaño de los contenedores estándar cambió: algunos se hicieron más grandes, otros se hicieron más pequeños. Como resultado, el tamaño de nuestras estructuras personalizadas también cambió.

Para resolver los problemas causados ​​por el cambio de tamaño, un colega mío pensó en aumentar artificialmente el tamaño de nuestras estructuras para compensar los cambios de tamaño de los miembros futuros para que las estructuras tengan el mismo tamaño, independientemente del tiempo de ejecución uso, evitando la corrupción de la pila en llamadas a funciones.

Personalmente, siento que esta "solución" es horrible porque si bien el tamaño importa, también lo hace el diseño de las estructuras. Para mí, aumentar la huella de memoria de todas las estructuras para arreglar problemas organizacionales parece realmente incorrecto.

Para abreviar, mi pregunta es: ¿es posible utilizar simultáneamente dos tiempos de ejecución diferentes (utilizando el truco descrito o cualquier otro truco) mientras se utilizan tipos distintos de C en los prototipos de función? ¿Tienes alguna experiencia buena/mala con respecto a una situación similar?

Respuesta

9

El STL nunca ha garantizado la compatibilidad binaria entre las diferentes versiones principales. Entonces, si tiene DLL con clases STL en la interfaz, debe usar el mismo compilador y el mismo estilo de CRT para el cliente de la DLL y la DLL misma.

Si usted quiere construir DLL que se puede utilizar de forma segura con diferentes versiones del compilador, usted tiene algunas opciones, como:

  1. exponer una pura C interfaz (DLL puede ser escrito en C++, pero la interfaz debe ser pura C, y las excepciones de C++ no pueden cruzar los límites de la DLL).
  2. Exponer interfaces abstractas en la interfaz DLL, como se explica en este article.
  3. Utilice COM.
+0

'1.' no es una opción, pero' 2.' podría funcionar bien. Muchas gracias por el artículo vinculado. – ereOn

+0

@ereOn: De nada. –

1

Debes asegurarte de que todo lo que necesite usar esas bibliotecas antiguas esté vinculado y compilarse contra los archivos de encabezado que vienen con esa versión de esas bibliotecas. No hay otra manera de hacerlo, porque C++ debe poder ver los archivos de cabecera para saber cómo abordar cualquier estructura de datos.

Me da la impresión de su pregunta que se vinculará con algunas bibliotecas que a su vez están compiladas y vinculadas con el tiempo de ejecución de VC9, en cuyo caso puede ser posible vincular el resto del código con VC10, siempre y cuando las bibliotecas no expongan ninguno de los tipos de biblioteca de VC9 en sus interfaces. Digo 'bien puede ser', esta es un área cargada de trampas y trampas y, en general, diría que debes usar el mismo tiempo de ejecución siempre que sea posible. Lo último que necesita es que el compilador se confunda en cuanto a la versión de std :: vector de la que está hablando (y puede garantizar que los programadores se confundirán también, incluso si puede persuadir al compilador y al enlazador para que lo resuelvan) .

Es más desagradable, pero es más fácil, simplemente mantener el tiempo de ejecución anterior hasta que ya no se requiera en ninguna máquina de destino.

+0

Gracias por su respuesta. Ya migramos todo nuestro código base a VC10, y al igual que si la situación no fuera mala, nuestro control de versiones de código fuente (VSS) hace que sea muy difícil, si no imposible, retrotraer estos cambios, por lo que volver a cambiar a VC9 es ya no es una opción :( – ereOn

+0

Eso no es realmente una característica esperada de un sistema de control de versiones. Lo siento por ti, creo que nuestra solución de control de versiones aquí sería aún peor, es demasiado empresarial para hacer cosas como revertir, ramificar o no bloqueando globalmente los archivos en el proceso de pago. –

+1

Por 'empresarial' te refieres a 'viejo y apenas funcional', ¿no? VSS realmente es terrible, simpatizo. Parece que estás en una situación desagradable. –

1

He hecho esto antes, rellenando las estructuras de una manera similar. Sí, puedes usar dos tiempos de ejecución diferentes y debería funcionar bien siempre que los ABI sean iguales: aquí es donde golpearás la pared cuando las estructuras comiencen a cambiar de tamaño, y moviendo C++ (donde el ABI está por todas partes) sobre Los límites de DLL son realmente muy complicados. Especialmente dado que VC10 tiene bastantes cambios en anticipación de C++ 11. Utilizo C en lo que respecta a las DLL, enteramente por las garantías que me brinda en términos de compatibilidad binaria.

Es difícil para mí ofrecer un caso específico en el que las cosas realmente se lo comen, pero permítanme ponerlo de esta manera: son los insectos que no anticipan lo que obtendrán, y este es un verdadero nido de avispas .

Cuestiones relacionadas