P /调用:C#P /调用C函数是否根据平台(X86与X64)返回不同的值?

时间:2019-01-23 19:18:47

标签: c# .net .net-core pinvoke

我问这个问题很荒谬,但是我有一个问题已经看了几个小时了,我一生都无法找出问题所在。

我在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);

内部类在.NET项目中定义,该项目构建2个程序集,其中1个用于.NET Framework,一个用于.NET Core。

我创建了一个小型的.NET命令行应用程序,该应用程序同时加载.NET程序集和C DLL并按如下所示调用函数:

var isSupported = NativeImport.cs_support(65503);

现在这是我不知道的有趣之处。如果我以应用程序为目标X86调用该函数一次,以应用程序为X64调用一次(因此加载了C DLL的X86或X64版本),则得到不同的值!更奇怪的是X64版本返回正确的值,而X86版本没有返回正确的值!

我可以访问C DLL的源代码,并且它没有处理器指令可以根据目标平台为同一输入返回不同的值。实际上,C语言代码非常简单,无论目标平台是什么,都应该为相同的输入返回相同的值。

此外,当我创建一个小型C命令行应用程序进行测试时,无论目标平台是什么,都将返回相同的正确值。

因此,似乎只有当.NET和P / Invoked加载C DLL时,我才能看到此行为!

所以我的问题是,为什么会这样?是否有一些怪异的P / Invoke行为会导致我必须注意这一点?

如果这很重要,我将在Windows 10 64位上运行。

谢谢!

1 个答案:

答案 0 :(得分:3)

从评论中的讨论中可以明显看出,问题是由本机函数返回_Bool值(类型_Bool的字节大小为1)引起的。

但是,默认情况下,.NET编组器将C#bool与Windows API数据类型BOOL进出C#_Bool,其字节大小为4(也为see here)。 / p>

要正确地编组单字节bool值,需要明确指示编组器将C#[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool cs_support(int queryOption); 值编组为单个字节:

#menu-primary-coach li:hover{
   /*#menu-primary-coach is the id of the lu*/
   background-color: #c7143a !important;
}