c# - P/Invoke:C# P/Invoking C 函数根据平台返回不同的值(X86 与 X64)?
问题描述
问这个问题我觉得很荒谬,但我有一个问题我已经研究了好几个小时了,我一辈子都无法弄清楚出了什么问题。
我在 C DLL 中定义了以下函数签名:
__declspec(dllexport) _Bool __cdecl cs_support(int query);
我在内部类中创建了以下 P/Invoke 签名等效项:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool cs_support(int queryOption);
内部类在构建 2 个程序集的 .NET 项目中定义,1 个用于 .NET Framework,1 个用于 .NET Core。
我创建了一个小的 .NET 命令行应用程序,它同时加载 .NET 程序集和 C DLL,并按如下方式调用函数:
var isSupported = NativeImport.cs_support(65503);
现在这是我无法弄清楚的有趣之处。如果应用程序以 X86 为目标,我调用该函数一次,如果它以 X64 为目标(因此加载了 C DLL 的 X86 或 X64 版本),我得到不同的值!更奇怪的是X64版本返回正确的值,而X86版本没有!
我可以访问 C DLL 的源代码,它没有处理器指令可以根据目标平台为相同的输入返回不同的值。无论目标平台如何,C 代码实际上都非常简单,应该为相同的输入返回相同的值。
此外,当我创建一个小型 C 命令行应用程序进行测试时,无论目标平台如何,都会返回相同的正确值。
因此,似乎只有当 C DLL 由 .NET 和 P/Invoked 加载时,我才会看到这种行为!
所以我的问题是,为什么会这样?是否有一些奇怪的 P/Invoke 行为会导致我不得不提防这种情况?
如果这很重要,我正在 Windows 10 64 位上运行。
谢谢!
解决方案
从评论中的讨论可以清楚地看出,问题是由本机函数返回一个_Bool
值引起的,该类型_Bool
的字节大小为 1。
但是,默认情况下,.NET 编组器将 C# 编组bool
到和来自 Windows API 数据类型BOOL
,其字节大小为 4(另见此处)。
要正确编组单字节_Bool
值,需要明确指示编组器将 C#bool
值编组为单字节:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool cs_support(int queryOption);
推荐阅读
- excel - 将 IF 语句与使用 .value 的字符串一起使用
- mstest - TFS 构建服务器无法与控制器通信以进行负载测试
- php - 我的函数中的布尔值不适用于确定文件大小
- reactjs - 向封闭网络中的用户开放 Rails API
- c++ - 使用动态数组操作内存中的垃圾
- java - Java Textio 文件添加
- python - 如何从美丽汤中的a类中提取href?
- swift - 切换 swiftUI toggle() 时如何触发操作?
- svg - 在 SVG 的 X 轴上添加上标和下标
- python - 我的代码中出现 TypeError:不支持的操作数类型 for ^: 'bytes' and 'bytes'