为啥将ATL项目升级到VS2015.1后regsvr32会失败?

Posted

技术标签:

【中文标题】为啥将ATL项目升级到VS2015.1后regsvr32会失败?【英文标题】:Why does regsvr32 fail after upgrading an ATL project to VS2015.1?为什么将ATL项目升级到VS2015.1后regsvr32会失败? 【发布时间】:2016-08-13 08:32:33 【问题描述】:

在我当前的项目中,我有多个相互依赖的 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 作品。

这确实会在 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 似乎没有任何区别(如果我正确理解链接的博客)。

【问题讨论】:

当您链接未重新编译的代码时,您会遇到这种不幸。一个通常使用旧版本 ATL 构建的库。 @HansPassant 我已经重建了整个解决方案(包括公共项目),以便将其链接到最新版本的 ATL。所以你认为问题在于至少有一个库链接到了旧版本的 ATL 版本? 【参考方案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 引用添加到引用它的项目的附加依赖项

【讨论】:

以上是关于为啥将ATL项目升级到VS2015.1后regsvr32会失败?的主要内容,如果未能解决你的问题,请参考以下文章

当项目名称带有连字符时,为啥 VS 2010 ATL 简单对象向导不会生成 .cpp/.h 文件?

安装 VS 2015.1 / .NET 4.6.1 后 Silverlight 5 SDK SLSvcUtil 错误

将 C++ ATL 可执行应用程序从 VS2003 迁移到 VS2013

ATL Trace 中定义的类别过多

VS2017 新建MFC项目时只有ATL选择,怎么才能建有窗体的MFC?

Visual Studio:无法将ATL类添加到ATL项目中?