2009-08-04 12 views
6

Estoy usando Visual C++ 2008 SP1. Tengo una aplicación compilada en modo de depuración, pero enlaces contra una biblioteca en modo de lanzamiento.Vinculación con la biblioteca en versión y .exe en errores de depuración en Visual Studio

Estoy recibiendo un bloqueo en el inicio de la aplicación. Para hacer el problema más pequeño, creé una solución simple con 2 proyectos:

  • lib_release (genera un .lib, en modo de lanzamiento)
  • exec_using_lib_release (genereates un .exe, en modo de depuración)

El proyecto 'lib_release' es lo suficientemente simple para tener una clase simple:

//Foo.h 
#include <vector> 
class Foo { 
    std::vector<int> v; 
    public: 
    void doSomething(); 
}; 
//Foo.cpp 
#include "Foo.h" 
void Foo::doSomething() {} 

El proyecto 'exec_using_lib_release' es tan simple como esto:

//main.cpp 
#include "Foo.h" 
int main() { 
    Foo foo; 
    foo.doSomething(); 
    return 0; 
} 

Y se bloquea, es el mismo problema reportado por How do you build a debug .exe (MSVCRTD.lib) against a release built lib (MSVCRT.lib)?, pero su respuesta no funcionó para mí.

Recibo las mismas advertencias del enlazador, probé con los mismos pasos, pero ninguno funcionó. ¿Se me escapa algo?

EDIT:

Por lib_release (que crea una biblioteca en modo de lanzamiento), estoy usando multihilo (/ MT), y al exec_using_lib_release, estoy usando multihilo Depurar (/ MTd). Creo que esta es la forma esperada de hacerlo, ya que quiero que la .lib se cree sin información de depuración. Leí el documento al MSDN Runtime library y esas son las configuraciones de vinculación contra el CRT de una manera estática.

No tengo 'Common Language Runtime Support' tampoco.

+0

Es este el código exacto de la muestra (foo.h) o es simplificado y no lo que realmente intentado? – Timbo

+0

@Timbo es casi lo mismo, solo que la clase Foo tiene una versión .cpp que tiene implementado el método doSomething(). –

+0

¿Es usted el proveedor de la lib estática o es un tercero? – KJAWolf

Respuesta

8

No tiene tiene para usar los mismos tiempos de ejecución para los módulos de versión y depuración (pero ayuda), siempre y cuando siga reglas muy específicas: nunca mezcle y combine el acceso a la memoria asignada usando cada tiempo de ejecución.

En pocas palabras, si tiene una rutina en un dll que asigna algo de memoria y la devuelve a la persona que llama, la persona que llama nunca debe liberarla; debe crear una función en la DLL original que libere la memoria. De esta forma estás a salvo de errores de tiempo de ejecución.

Si considera que las DLL de Windows están compiladas únicamente a partir de versiones (a menos que tenga la versión de depuración de Windows), pero las usa desde sus aplicaciones de depuración, verá cómo esto importa.

Su problema ahora es que está utilizando una biblioteca estática, ya no hay límites dll y las llamadas en lib se compilan utilizando la versión estática del tiempo de ejecución de C. Si su exe usa la versión dll dinámica del tiempo de ejecución, encontrará que el enlazador está usando esa en lugar de la que usa su lib estática ... y obtendrá bloqueos.

Entonces, podría reconstruir su lib como dll; o puede asegurarse de que ambos usen la misma biblioteca CRT; o puede asegurarse de que ambos usen el mismo tipo de CRT, es decir, la versión dll o la versión estática, manteniendo las diferencias de depuración/versión.

Al menos, creo que este es su problema: ¿cuáles son las configuraciones de "generación de código, biblioteca de tiempo de ejecución"?

+0

Sí, ese es mi problema. Sin embargo, ¿cómo hacen los desarrolladores de lib que liberan sus compilaciones compiladas como 'release' para hacerlos 'enlazables' con un programa que se ejecuta en modo de depuración? ¿Siguen estas 'reglas estrictas' que estás diciendo? –

+0

¿está utilizando el CRT estático o dinámico en nuestra lib? Si desea que sea completamente portátil, utilice la versión estática ya que todas las llamadas CRT se integrarán en la lib. Alternativamente construye tu exe con el lanzamiento CRT. No estoy seguro de que haya muchas librerías estáticas comerciales, las personas tienden a suministrar dlls en su lugar. – gbjbaanb

+0

Siguiendo estas reglas específicas, ¿podría haber algún problema con el empaquetado diferente en los modos de depuración? – TripleS

2

El problema aquí es que la depuración usará la versión de depuración del tiempo de ejecución de c y la versión usará la versión de lanzamiento del tiempo de ejecución c y cuando intente acceder a la memoria a través del límite dll se ejecutará incorrectamente tiempo y crash. Es mejor usar solo versiones de depuración juntas (o versión)

+1

¿dónde ve alguna asignación dinámica? –

5

Para la combinación de problemas de liberación y depuración que las personas anteriores mencionaron, esos problemas no aparecerían hasta que la biblioteca de tiempo de ejecución incorrecta intentara desasignar. Creo que lo que te estás encontrando es que VS 2008 tiene habilitada la depuración de iteradores por defecto, por lo que tu lib y tu exe hacen referencia a diferentes implementaciones de std :: vector. Deberá agregar _HAS_ITERATOR_DEBUGGING = 0 a la configuración de su preprocesador. Luego comenzará a abordar el problema de diferentes montones para los diferentes tiempos de ejecución. En el pasado, teníamos reglas y políticas diferentes para evitar esto, pero ahora solo confiamos en un entorno de compilación coherente: no mezcle ni combine.

0

La biblioteca adjunta no debe compartir recursos CRT a través del límite de la biblioteca. Para el código C, la memoria asignada dinámicamente debe desasignarse en el mismo lado del límite. Para el código C++, puede usar el espacio de nombres estándar dentro de su archivo DLL, pero los objetos que usan el espacio de nombres std se deben pasar a través del límite de la biblioteca.

ver this respuesta a una pregunta similar

Cuestiones relacionadas