为什么在将ATL项目升级到VS2015.1后regsvr32失败?

时间:2016-04-20 14:52:23

标签: c++ com visual-studio-2015 atl 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开始,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 ++运行时库

     

Debug Assertion失败!

     

程序: ... \ 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似乎没有任何区别(如果我理解正确的链接博客)。

1 个答案:

答案 0 :(得分:0)

好的,我终于想通了。问题与将跟踪类别声明为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,则跟踪类别现在导出到库,这对于公共项目是正确的。引用此库的所有项目都是导入定义(通过包含从{id}文件创建的Common.h)。如果将跟踪类别定义为静态,则每个库都会在其上定义一个类别。我认为这是我所面临的错误的原因。

现在在公共项目的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