Почему после обновления проекта ATL до VS2015.1 происходит сбой regsvr32?

В моем текущем проекте у меня есть несколько проектов ATL, которые зависят друг от друга. Один из них называется Common и определяет категорию трассировки, другие проекты могут использовать ее для вывода информации трассировки.

Я определил категорию из файла 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 (если я правильно понял связанный блог).


person Carsten    schedule 20.04.2016    source источник
comment
Это своего рода неудача, когда вы связываете код, который не был перекомпилирован. Библиотека, обычно построенная с использованием старой версии ATL.   -  person Hans Passant    schedule 20.04.2016
comment
@HansPassant Я уже перестроил все решение (включая общий проект), чтобы связать его с последней версией ATL. Так вы думаете, что проблема в том, что хотя бы одна библиотека связана с более старой версией ATL?   -  person Carsten    schedule 20.04.2016


Ответы (1)


Ладно, наконец-то я в этом разобрался. Проблема была связана с объявлением категории трассировки как 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 к дополнительным зависимостям проектов, которые на нее ссылаются.

person Carsten    schedule 21.04.2016