P/Invoke:C# P/Invoking 一个 C 函数 Returns 不同的值取决于平台(X86 与 X64)?
P/Invoke: C# P/Invoking a C Function Returns Different Values Depending on Platform (X86 vs. X64)?
我觉得问这个问题很荒谬,但我有一个问题我已经研究了几个小时了,但我终究无法找出问题所在。
我在 C DLL 中定义了以下函数签名:
__declspec(dllexport) _Bool __cdecl cs_support(int query);
我在内部 class 中创建了以下 P/Invoke 等效签名:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool cs_support(int queryOption);
内部 class 在构建 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版本return是正确的值,而X86版本却不是!
我可以访问 C DLL 的源代码,并且它没有处理器指令 return 基于目标平台的相同输入的不同值。 C 代码实际上非常简单,无论目标平台如何,都应该 return 相同输入的相同值。
此外,当我创建一个小型 C 命令行应用程序进行测试时,无论目标平台如何,都会 return 编辑相同的正确值。
因此,似乎只有当 C DLL 由 .NET 和 P/Invoked 加载时,我才会看到此行为!
所以我的问题是,为什么会这样?是否有一些奇怪的 P/Invoke 行为会导致我必须提防?
我是 运行 Windows 10 64 位,如果重要的话。
谢谢!
根据评论中的讨论,很明显问题是由返回 _Bool
值的本机函数引起的,类型 _Bool
的字节大小为 1。
但是,默认情况下,.NET 编组器将 C# bool
编组到 Windows API 数据类型 BOOL
,其字节大小为 4 (也 see here)。
要正确编组单字节 _Bool
值,需要明确指示编组器将 C# bool
值编组为单字节:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool cs_support(int queryOption);
我觉得问这个问题很荒谬,但我有一个问题我已经研究了几个小时了,但我终究无法找出问题所在。
我在 C DLL 中定义了以下函数签名:
__declspec(dllexport) _Bool __cdecl cs_support(int query);
我在内部 class 中创建了以下 P/Invoke 等效签名:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool cs_support(int queryOption);
内部 class 在构建 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版本return是正确的值,而X86版本却不是!
我可以访问 C DLL 的源代码,并且它没有处理器指令 return 基于目标平台的相同输入的不同值。 C 代码实际上非常简单,无论目标平台如何,都应该 return 相同输入的相同值。
此外,当我创建一个小型 C 命令行应用程序进行测试时,无论目标平台如何,都会 return 编辑相同的正确值。
因此,似乎只有当 C DLL 由 .NET 和 P/Invoked 加载时,我才会看到此行为!
所以我的问题是,为什么会这样?是否有一些奇怪的 P/Invoke 行为会导致我必须提防?
我是 运行 Windows 10 64 位,如果重要的话。
谢谢!
根据评论中的讨论,很明显问题是由返回 _Bool
值的本机函数引起的,类型 _Bool
的字节大小为 1。
但是,默认情况下,.NET 编组器将 C# bool
编组到 Windows API 数据类型 BOOL
,其字节大小为 4 (也 see here)。
要正确编组单字节 _Bool
值,需要明确指示编组器将 C# bool
值编组为单字节:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool cs_support(int queryOption);