我在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
文件中完全没问题,因为没有导入其他任何地方。