在 C# 中从 C++ .DLL 加载值总是 returns true

Loading value from C++ .DLL in C# always returns true

我正在努力学习如何制作 C++ DLL,所以我很容易错过一些非常基础的东西。

我目前正在用 C++ 创建 DLL,然后将其加载到用 C# 编写的测试环境中

测试环境使用 C#,因为我发现 Windows 构建原型 GUI 最简单。

我的 DLL (C++) 中有一个定义

#define BUILD_FOR_TESTBED

以及我创建的一个函数,用于查找它是否已定义

//header file
extern "C" _declspec(dllexport) extern bool WasBuiltForTestbed();

//source file
bool WasBuiltForTestbed()
{
#ifdef BUILD_FOR_TESTBED

    return true;

#endif // BUILD_FOR_TESTBED
#ifndef BUILD_FOR_TESTBED

    return false;

#endif // BUILD_FOR_TESTBED//
}

然后我在测试环境 (C#) 中加载函数

[DllImport(LIBRARY_PATH, CharSet = CharSet.Unicode)]
public static extern bool WasBuiltForTestbed();

并写入测试环境的控制台

Console.WriteLine("Built For Testbed: " + WasBuiltForTestbed());

无论我做什么 WasBuiltForTestbed() return加载到测试环境后都是真的。

问: 我的问题是,我在这里缺少什么使函数始终 return 为真?如何使函数 return 无论 BUILD_FOR_TESTBED 是否已定义?

到目前为止我尝试过的测试:

“短路”函数并直接使其“return”为真或假。它仍然只有 return 是真的。

bool WasBuiltForTestbed() { return false; }

清理库 (C++) 和测试环境 (C#) 构建。然后重建

正在将库中函数 WasBuiltForTestbed() 的名称更改为 WasBuiltForrTestbed()。测试环境无法加载函数,因此它肯定会找到它认为是函数的东西并对其进行评估。

感谢任何帮助。

.NET 使用 4 字节 bool,而 Visual C++ 使用 1 字节 bool。因此,您需要一个编组指令来告诉编组器即将到来的只是一个字节。事实上,除了 bool 之外,它只是整理了 3 个字节的垃圾。垃圾通常是非零的,这就是为什么你的函数出现 return true.

将此添加到 DllImport。

[return:MarshalAs(UnmanagedType.I1)]

至于为什么 .NET 选择 bool 4 字节,主要原因可能是支持与 C++ Windows API 的互操作,后者使用 4 字节 BOOL,而不是 Visual C++ 的标准 C++ 实现,它使用 1 字节 bool.

(为什么要注意?好吧,标准 C++ 实际上并没有指定 bool 的大小...)