Невозможно передать std::wstring через DLL

Я создал проект в Visual Studio 2010 для написания модульных тестов для существующей библиотеки MFC. Я использую фреймворк для модульного теста с одним заголовком и связан с библиотекой lib MFC DLL из проекта модульного теста. Я пытаюсь построить класс, который занимает std::wstring в этом конструкторе. Вот как выглядит мой тест:

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);
}

куда Foobar это класс, экспортируемый из тестируемой MFC DLL. Однако среда тестирования сообщает о неожиданном исключении. Я отследил это до std::wstringконструктор копирования при копировании строки в Foobarконструктор. Отладчик MSVC сообщает об исходной строке как <Bad Ptr>,

Я создал фиктивный конструктор, Foobar::Foobar(long num, IDbService& db) и все значения (включая IDbService&) попадаются просто отлично.

И MFC DLL, и мой модульный тестовый EXE-файл совместно используют лист свойств, который должен поддерживать флаги компилятора эквивалентными. Я собираю и запускаю тест в режиме отладки. Любые идеи, почему std::wstring не можете скопировать через DLL?

1 ответ

Решение

Вы должны проверить, что и EXE, и DLL динамически связаны с одной и той же CRT отладки (/MDd опция компилятора). Убедитесь, что и другие настройки, такие как _HAS_ITERATOR_DEBUGGING одинаковы для EXE и DLL.

(Ярлык может быть просто использовать const wchar_t* вместо std::wstring на интерфейсе класса, и просто построить std::wstring из необработанного указателя внутри тела конструктора).

РЕДАКТИРОВАТЬ: Вы подтвердили, что CRT несоответствие (т.е. EXE, созданный с /MD DLL против /MDd) была проблема. Дело в том, что одно и то же имя класса std::wstring означает два разных класса в отладочных сборках (/MDd) и в сборках релиза (/MD). Фактически, в отладочных сборках может быть дополнительная механика внутри реализации класса, чтобы помочь отладке; эта механика может привести к неэффективности, поэтому она удаляется в релизных сборках. Итак, внутренняя структура отладочной сборки std::wstring отличается от релиза сборки std::wstring (например, если вы пытаетесь распечатать сырой sizeof из std::wstring экземпляры, вы можете найти разные номера в сборках релизов и сборках отладки). Итак, EXE построен с /MD ожидал релиз-билда std::wstring; вместо этого DLL построена с /MDd ожидал отладочной сборки std::wstring: есть несоответствие между этими двумя ожиданиями (один модуль ожидает класс X но другой модуль дает класс Y) и поэтому у вас есть сбой.

Другие вопросы по тегам