c# - 在 C# 中从 C++ .DLL 加载值始终返回 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() 一旦加载到测试环境中就会返回 true。
问:我的问题是,我在这里缺少什么使函数始终返回 true?无论是否定义了 BUILD_FOR_TESTBED,如何使函数返回?
到目前为止我尝试过的测试:
“短路”函数并使其直接“返回”真或假。它仍然只返回 true。
bool WasBuiltForTestbed() { return false; }
清理库 (C++) 和测试环境 (C#) 构建。然后重建
在库中将函数 WasBuiltForTestbed() 的名称更改为 WasBuiltForrTestbed()。测试环境未能加载函数,所以它肯定会找到它认为是函数的东西并评估它。
任何帮助表示赞赏。
解决方案
.NET 使用 4 字节bool
,但 Visual C++ 使用 1 字节bool
。因此,您需要一个封送处理指令来告诉封送处理程序输入的内容只是一个字节。事实上,除了你的bool
. 垃圾通常不为零,这就是您的函数似乎返回的原因true
。
将此添加到 DllImport。
[return:MarshalAs(UnmanagedType.I1)]
至于 .NET 选择bool
4 字节的原因,可能主要原因是支持与使用 4 字节的 C++ Windows API 互操作BOOL
,而不是使用 1 字节的 Visual C++ 标准 C++ 实现bool
.
(为什么要注意?好吧,标准 C++ 实际上并没有指定bool
...的大小)
推荐阅读
- java - 在 springORM 中声明 org.springframework.orm.hibernate5.LocalSessionFactoryBean 的 bean 显示错误
- linux - 从 linux 移动 Azure SMB 文件共享中的文件
- angular - 类型 '
' 不可分配给类型 ' '。类型 ' 中缺少索引签名 ' - oracle - ORA-02019: 未找到远程数据库的连接描述 - 过程调用
- activemq-artemis - Artemis 集群抛出 ClassNotFoundException:org.hornetq.core.remoting.impl.netty.NettyConnectorFactory
- java - 用 allatori 混淆太多
- python - 如何在 Sphinx 文档中的某些特定功能之后插入图像?
- javascript - 用表达式中的表达式传递变量中的变量 - JavaScript
- arrays - 如何创建并推送到共享或分布式数组数组?
- excel - Qt QAxObject - 在 querySubObject 和 Cell 属性上查找 Excell API/SDK 文档