В моем текущем проекте у меня есть несколько проектов ATL, которые зависят друг от друга. Один из них называется «Общий» и определяет категорию трассировки, которую другие проекты могут использовать для распечатки информации трассировки.
Я определил категорию из файла IDL следующим образом:
cpp_quote("static ATL::CTraceCategory DATA_LAYER(_T(\"Data Layer\"), 1);")
По сути, это означает следующее определение в файле общего заголовка, другие проекты включают в себя получение информации об интерфейсах «общего» проекта.
static ATL::CTraceCategory DATA_LAYER(_T("Data Layer"), 1);
Теперь, начиная с Visual Studio 2013, изменение в том, как отслеживание работает.
Это приводит к критическим изменениям в некоторых случаях использования
ATL::CTraceCategory
класс, который потребует изменений в исходном коде при переходе на Visual Studio 2013.
И действительно, мне пришлось изменить строку выше, удалив второй параметр:
cpp_quote("static ATL::CTraceCategory DATA_LAYER(_T(\"Data Layer\"));")
Теперь все строится снова, но проблема возникает, как только я пытаюсь перестроить любой проект, который использует категорию трассировки. После успешного завершения сборки компилятор автоматически регистрирует компонент. И во время regsvr32 /s "C:\...\Common.dll"
Я всегда получаю отладочную диссертацию, подобную этой:
Библиотека времени выполнения Microsoft Visual C ++
Ошибка отладки!
Программа: …\ X64 \ Debug \ Common.dll
Файл: c: \ program files (x86) \ Microsoft Visual Studio 14.0 \ vc \ atlmfc \ include \ atltrace.h
Линия: 337
Выражение:
false && "Too many categories defined"
Это также происходит, когда я пытаюсь зарегистрировать компонент вручную. Только проекты, которые не зависят от общего проекта и поэтому не используют какую-либо категорию трассировки, регистрируются успешно.
У кого-нибудь есть решение для этого? Я также хотел бы принять решение, которое показывает другой способ отслеживания в ATL, так как нет никакой разницы в использовании DebugOutputString
вместо этого (если я правильно понял связанный блог).
Хорошо, я наконец понял это. Проблема была связана с объявлением категории трассировки как static
, Я понятия не имею, почему это встроено в предыдущие версии Visual Studio. Во всяком случае, вот исправление: во-первых, я изменил определение категории трассировки в моем Common.idl
файл:
cpp_quote("#ifdef DEFINE_EXPORTS")
cpp_quote("__declspec(dllexport) extern ATL::CTraceCategory DATA_LAYER;")
cpp_quote("#else // DEFINE_EXPORTS")
cpp_quote("__declspec(dllimport) ATL::CTraceCategory DATA_LAYER;")
cpp_quote("#endif // DEFINE_EXPORTS")
Как видите, категория трассировки теперь экспортируется в библиотеку, если DEFINE_EXPORTS
определяется, что верно для общего проекта. Все проекты, ссылающиеся на эту библиотеку, импортируют определение (включая Common.h
, который создается из файла idl). Если вы определяете категорию трассировки как статическую, каждая библиотека определяет категорию самостоятельно. Я думаю, что это было причиной ошибки, с которой я столкнулся.
Теперь внутри dllmain.cpp
В файле общего проекта я определяю категории трасс:
#if (_MSC_VER >= 1800)
ATL::CTraceCategory DATA_LAYER(_T("Data Layer"));
#else
ATL::CTraceCategory DATA_LAYER(_T("Data Layer"), 1);
#endif
Обратите внимание, что код переключается между двумя конструкторами в зависимости от версии VC ++, с которой он скомпилирован. Должно быть возможно избавиться от этого с помощью CTraceCategoryEx
шаблон, но я придерживаюсь этого метода на данный момент.
Наконец все, что мне нужно было сделать, это добавить Common.lib
ссылка на Дополнительные зависимости проектов, ссылающихся на него.
Других решений пока нет …