我在 VS 2017 中有一个基本的 C++/CLI DLL,它定义了下面描述的包装类。项目属性设置为生成以 .NET 4.6.1 作为目标的 CLR。
#include "ApiManagerWrapper.h" // very basic CLI wrapper header
#include "Handler.h" // This header is an API example that includes windows.h
using namespace System;
using namespace std;
namespace CLI
{
ApiManager::ApiManager()
: ManagedObject(new GXP_API::ApiManager())
{
Console::WriteLine("Creating a new ApiManager-wrapper object!");
}
}
我需要重用一个包含 windows.h 的 C++ 文件(handler.h,来自 API devkit),主要是为了使用 HANDLE 和 CRITICAL_SECTION 结构。我知道这一点是因为如果我删除 handler.h 标头中包含的 windows.h(以及使用上述结构的大部分代码),CLI 包装器 DLL 就可以正常编译。
问题在于 FILETIME 是在 windows.h (minwinbase.h) 包含的标头之一和命名空间 System::Runtime::InteropServices 中定义的。该错误在 VS 2017 中报告为 E0266,并带有一个线程链接,该线程建议限定 FILETIME 的使用与预期使用范围 (::FILETIME)。然而,在这种情况下这是不可能的,因为该标头来自操作系统。我还需要使用 System 命名空间,因为它是 CLI 组装机制的基础。
如何解决这个冲突?有没有办法不使用系统命名空间的给定部分?有什么方法可以指导编译器如何解决冲突吗?
我遇到了一些类似的问题,我的猜测是您在头文件之一中使用了
using namespace
。
<windows.h>
中的许多定义与 c++/cli 包装器中的定义相同,因为包装器包装了它们。这就是为什么它们位于不同的命名空间中。
例如,通过头文件中的 using namespace System::Runtime::InteropServices
,在导入头文件的任何地方,现在对于 Windows 头文件中也存在的任何定义都存在潜在的冲突。如果您知道有一个文件导入了两个标头,那么您定义了“相同”实体两次,现在您就遇到了歧义问题。因此,在所有头文件中,您需要剪切
using namespace
并完全限定所有实体。这可以解决您的问题。旁注:
using namespace
在
.cpp
文件中完美无缺,因为没有在其他任何地方导入。