2012-07-25 12 views
15

¿Es una mala práctica usar una versión de lanzamiento de una biblioteca de terceros en depuración binaria?Mezcla de errores y biblioteca de versiones/binario - ¿mala práctica?

Estoy utilizando una biblioteca de terceros y compilé una biblioteca de .lib de lanzamiento. Mi exe está en desarrollo de modo de depuración. Luego me dieron:

error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in test1.obj 

Después de algunas google he encontrado que es porque estoy tratando de mezclar con la liberación de depuración, y probablemente debería compilar la librería en modo de depuración o de otra manera salir del paso con la macro _ITERATOR_DEBUG_LEVEL. Pero solo tengo curiosidad si esa es la forma recomendada y por qué. Parece engorroso que deba compilar y mantener un registro de los archivos binarios tanto de versión como de depuración para cada biblioteca de terceros que pretendo utilizar, lo cual será muy pronto, sin tener la intención de depurar este código.

+0

¿No puede ponerse en contacto con este tercero para obtener una versión de depuración o crear una versión de depuración usted mismo? –

+0

Es más que una mala práctica: está casi garantizado que el programa se bloqueará o hará cosas malas. Antes de VS2010 podías enlazar de todos modos, para descubrir en el tiempo de ejecución extraños errores. Ahora al menos te lo impiden. –

+1

@JesseGood Sí, tengo el código fuente y acabo de compilar la versión de depuración. Problema resuelto. Me preguntaba si puedo salirme con la compilación y el seguimiento de un modo. ¡Aparentemente no! –

Respuesta

26

Mezclar el código de depuración y liberación es una mala práctica. El problema es que las diferentes versiones pueden depender de diferentes partes fundamentales de la biblioteca de tiempo de ejecución de C++, como cómo se asigna la memoria, las estructuras para elementos como iteradores pueden ser diferentes, se podría generar código adicional para realizar operaciones (por ejemplo, iteradores marcados).

Es lo mismo que mezclar archivos de biblioteca creados con cualquier otra configuración diferente. Imagine un caso en el que un archivo de encabezado contiene una estructura que es utilizada tanto por la aplicación como por la biblioteca. La biblioteca está construida con el empaquetado de la estructura y la alineación configurados en un valor y la aplicación construida con otro. No hay garantías de que el paso de la estructura desde la aplicación a la biblioteca funcione, ya que podrían variar en tamaño y posiciones de miembros.

¿Es posible construir sus bibliotecas de terceros como archivos DLL? Suponiendo que la interfaz para cualquier función es más limpia y no intenta pasar ningún objeto STL, podrá mezclar una aplicación de depuración con DLL de lanzamiento sin problemas.

+0

En particular, los contenedores estándar y los iteradores son diferentes e incompatibles. Ese es el cheque que está viendo: afecta el diseño de los iteradores al agregar campos adicionales. El std :: string stuff (solo) tiene compatibilidad para la compatibilidad entre Debug y Release, pero nada más en stl funcionará. –

+2

@ JDługosz std :: string explícitamente no es compatible entre los tiempos de ejecución. Un ejercicio entretenido es crear una DLL con solo la función '__declspec (dllexport) std :: string make_string()', compilar en Debug, luego crear un ejecutable de Release, vincular y llamar a la función. Cuando intenté 'std :: cout' la cadena devuelta, el bloqueo resultante fue bastante dramático. Esto está usando VS2013, pero ciertamente fue un problema con VS2010 y espero otras versiones también. [Aquí está] (https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/) una pequeña información de la boca del caballo. – Rai

+0

Bueno, la versión en particular en la que había incursionado tenía código para hacer que la depuración y el release std string (iterador o valor, ya no recuerdo) fueran intercompatibles. Creo que era más antiguo que el VS2010, pero no recuerdo exactamente cuánto tiempo pasó. –

5

El hecho de que no se compile debería ser suficiente para demostrar que es una mala práctica.

En cuanto al mantenimiento de compilaciones separadas, no necesita hacer eso. Aquí hay una solución que anteriormente funcionó para mí:

#ifdef _DEBUG 
#define DEBUG_WAS_DEFINED 
#undef _DEBUG 
#endif 

#include <culprit> 

#ifdef DEBUG_WAS_DEFINED 
#define _DEBUG 
#endif 

Quiero saber si esto funciona para ti.

Cuestiones relacionadas