P/Invoke:C#P/调用C函数会根据平台返回不同的值(X86与X64)?
我觉得问这个问题很可笑,但我有一个问题,我已经考虑了好几个小时了,我一辈子都搞不清楚到底出了什么问题 我在C DLL中定义了以下函数签名:P/Invoke:C#P/调用C函数会根据平台返回不同的值(X86与X64)?,c#,.net,.net-core,pinvoke,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
__declspec(dllexport) _Bool __cdecl cs_support(int query);
我在一个内部类中创建了以下p/Invoke签名等效项:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool cs_support(int queryOption);
内部类是在.NET项目中定义的,该项目构建了两个程序集,一个用于.NET Framework,另一个用于.NET Core
我创建了一个小型的.NET命令行应用程序,它加载.NET程序集和C DLL,并按如下方式调用函数:
var isSupported = NativeImport.cs_support(65503);
现在我想不出有什么有趣的地方。如果应用程序以X86为目标调用函数一次,如果它以X64为目标调用函数一次(因此加载了X86或X64版本的C DLL),则会得到不同的值!更奇怪的是,X64版本返回了正确的值,而X86版本却没有
我可以访问C DLL的源代码,并且它没有处理器指令来根据目标平台为同一输入输出返回不同的值。C代码实际上非常简单,无论目标平台如何,它都应该为相同的输入返回相同的值
此外,当我创建一个小型C命令行应用程序进行测试时,无论目标平台如何,都会返回相同的正确值
因此,似乎只有当C DLL被.NET加载并被p/调用时,我才会看到这种行为
所以我的问题是,为什么会发生这种情况?是否有一些奇怪的P/Invoke行为会导致这种情况,我必须小心
我运行的是64位Windows 10,如果这很重要的话
谢谢 从评论中的讨论可以清楚地看出,问题是由本机函数返回
\u Bool
值引起的,类型\u Bool
的字节大小为1
但是,默认情况下,.NET封送处理程序在Windows API数据类型bool
之间封送一个C#bool
,该数据类型的字节大小也为4
要正确地封送单字节\u Bool
值,需要明确指示封送员将C#Bool
值封送为单字节:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool cs_support(int queryOption);
从注释中的讨论可以清楚地看出,问题是由本机函数返回
\u Bool
值引起的,类型\u Bool
的字节大小为1
但是,默认情况下,.NET封送处理程序在Windows API数据类型bool
之间封送一个C#bool
,该数据类型的字节大小也为4
要正确地封送单字节\u Bool
值,需要明确指示封送员将C#Bool
值封送为单字节:
[DllImport("capstone", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool cs_support(int queryOption);
什么是
\u Bool
DLL中是否存在会溢出32位整数的数学运算?尽管如此,我想这会出现在命令行测试中,您可以查看dll日志调试信息,或者您可以将C调试器附加到.net应用程序以查看dll中发生了什么?您的\u Bool
是否真的基于Bool
,而不是Bool
?请看这里理解“本地”代码> BoOL < /C>和<代码> Boo.<代码>的不同之处:(<代码> BOOL 是C++数据类型,而bool
数据类型<代码> BOOLBOOL
数据类型,该数据类型的长度为4字节。在p/调用时,.NET封送器默认情况下将C#bool封送至Windows APIbool
(4字节),除非特别设置为不同的方式;-)什么是\u Bool
DLL中是否存在会溢出32位整数的数学运算?尽管如此,我想这会出现在命令行测试中,您可以查看dll日志调试信息,或者您可以将C调试器附加到.net应用程序以查看dll中发生了什么?您的\u Bool
是否真的基于Bool
,而不是Bool
?请看这里理解“本地”代码> BoOL < /C>和<代码> Boo.<代码>的不同之处:(<代码> BOOL 是C++数据类型,而bool
数据类型<代码> BOOLBOOL
数据类型,该数据类型的长度为4字节。在p/调用时,.NET封送器默认情况下将C#bool封送至Windows APIbool
(4字节),除非特别设置为不同的方式;-)