为什么将ATL项目升级到VS2015.1后regsvr32会失败?
Why does regsvr32 fail after upgrading an ATL project to VS2015.1?
在我当前的项目中,我有多个相互依赖的 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 年以来似乎有 a change in how tracing 作品。
This does cause source-breaking changes in some uses of the ATL::CTraceCategory
class, which will require changes in source code when migrating to Visual Studio 2013.
事实上,我不得不通过删除第二个参数来更改上面的行:
cpp_quote("static ATL::CTraceCategory DATA_LAYER(_T(\"Data Layer\"));")
现在一切都重新构建了,但是当我尝试重建任何使用跟踪类别的项目时,问题就出现了。构建成功完成后,编译器会自动注册该组件。在 regsvr32 /s "C:\...\Common.dll"
期间,我总是收到这样的调试断言:
Microsoft Visual C++ Runtime Library
Debug Assertion Failed!
Program: ...\x64\Debug\Common.dll
File: c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\atltrace.h
Line: 337
Expression: 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
引用添加到引用它的项目的 Additional Dependencies。
在我当前的项目中,我有多个相互依赖的 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 年以来似乎有 a change in how tracing 作品。
This does cause source-breaking changes in some uses of the
ATL::CTraceCategory
class, which will require changes in source code when migrating to Visual Studio 2013.
事实上,我不得不通过删除第二个参数来更改上面的行:
cpp_quote("static ATL::CTraceCategory DATA_LAYER(_T(\"Data Layer\"));")
现在一切都重新构建了,但是当我尝试重建任何使用跟踪类别的项目时,问题就出现了。构建成功完成后,编译器会自动注册该组件。在 regsvr32 /s "C:\...\Common.dll"
期间,我总是收到这样的调试断言:
Microsoft Visual C++ Runtime Library
Debug Assertion Failed!
Program: ...\x64\Debug\Common.dll
File: c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\atltrace.h
Line: 337
Expression:
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
引用添加到引用它的项目的 Additional Dependencies。