c++ - studio - No se puede pasar std:: wstring en DLL
visual studio installer (1)
Establecí un proyecto en Visual Studio 2010 para escribir pruebas de unidad en una DLL de MFC existente. Estoy utilizando un marco de prueba de unidad de un solo encabezado y vinculado al contenedor de lib de la DLL de MFC del proyecto de prueba de la unidad. Estoy tratando de construir una clase que tenga una std::wstring
en su constructor. Así es como se ve mi prueba:
TEST_CASE("MyProject/MyTest", "Do the test.")
{
MockDbService mockDbService;
Foobar foo(L"{F00DFACE-FEED-DEAD-BEEF-C0FFEEDECADE}", mockDbService);
foo.loadObject();
REQUIRE(mockDbService.getMethodInvokeCount("query()") >= 1);
}
Donde Foobar
es la clase exportada desde la DLL de MFC bajo prueba. Sin embargo, el marco de prueba informa una excepción inesperada. Lo std::wstring
al constructor de copias de std::wstring
cuando std::wstring
la cadena al constructor de Foobar
. El depurador MSVC informa la cadena de origen como <Bad Ptr>
.
Foobar::Foobar(long num, IDbService& db)
un constructor falso, Foobar::Foobar(long num, IDbService& db)
y todos los valores (incluido el IDbService&
) se encuentran muy bien.
Tanto el DLL de MFC como el EXE de prueba de mi unidad comparten una hoja de propiedades que debería mantener las banderas del compilador equivalentes. Estoy construyendo y ejecutando la prueba en modo de depuración. ¿Alguna idea de por qué std::wstring
no puede copiar a través de la DLL?
Debería comprobar que tanto el EXE como el DLL están dinámicamente vinculados con la misma depuración CRT ( /MDd
opción de compilador /MDd
). Asegúrese de que también otras configuraciones como _HAS_ITERATOR_DEBUGGING
sean las mismas tanto para el EXE como para el DLL.
(Un atajo podría ser simplemente usar const wchar_t*
lugar de std::wstring
en la interfaz de clase, y simplemente construir un std::wstring
desde el puntero sin procesar dentro del cuerpo del constructor).
EDITAR : confirmó que la discrepancia CRT (es decir, EXE construido con /MD
vs. DLL construido con /MDd
) era el problema. El hecho es que el mismo nombre de clase std::wstring
significa dos clases diferentes en compilaciones de depuración ( /MDd
) y en versiones de lanzamiento ( /MD
). De hecho, en las compilaciones de depuración puede haber mecanismos adicionales dentro de la implementación de la clase para ayudar a la depuración; esta mecánica puede introducir ineficiencias, por lo que se elimina en versiones de lanzamiento. Por lo tanto, la estructura interna de std::wstring
la estructura de depuración es diferente de std::wstring
de la versión de lanzamiento (por ejemplo, si intenta imprimir el std::wstring
instancias std::wstring
, puede encontrar diferentes números en compilaciones de versiones y depuración) . Por lo tanto, el EXE creado con /MD
esperaba std::wstring
release-build; en su lugar, el DLL creado con /MDd
esperaba el std::wstring
debug-build: hay una falta de coincidencia entre estas dos expectativas (un módulo espera la clase X
pero el otro módulo le da la clase Y
) y entonces tiene un bloqueo.