为啥将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