背景信息
我有一个 C 函数,它返回一个 void*
。
我开始测试两个项目之间的转换,将 true
或 false
分配给指针,回到 C# 中,我得到了 IntPtr
,我使用了 IntPtr.ToPointer()
函数,然后将其转换为一个字节,根据我读到的内容,这相当于 c# 中的 boolean。
这对我来说效果很好。
DLL导入:
[DllImport(Library.ruta,
SetLastError = true,
CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr test_boolean(int flag);
使用函数:
x = Library.test_boolean(1);
z = x.ToPointer();
Console.WriteLine("Prueba");
if (Convert.ToBoolean((byte)z))
Console.WriteLine("True");
else
Console.WriteLine("False");
问题
当我尝试执行相同操作但将 bool 数组分配给指针时,我无法在 C# 中将其恢复。
这就是 C 语言中的函数的样子
...
vpointer *chromosome;
chromosome = s_malloc(2*sizeof(boolean *));
if (flag == 1)
{
chromosome[0] = true;
chromosome[1] = true;
}
...
Return chromosome;
我尝试用 C# 做什么:
(1) 我尝试了相同的“转换”,这次是字节数组。这给了我一个空引用异常:
if (Convert.ToBoolean(((byte*)z)[1]))
Console.WriteLine("True");
else
Console.WriteLine("False");
(2) 由于这不起作用,经过一番研究,我尝试了 Marshal.Copy
函数,将指针复制到字节数组。尽管这次我没有得到任何异常,但我没有得到正确的结果。我的意思是,例如,如果数组的第一个 bool 值是假,我就会变成真。
C# 代码如下所示:
x = Library.test_boolean(1);
byte [] managedArray = new byte[2];
Marshal.Copy(x, managedArray, 0, 2);
foreach (var qq in managedArray)
{
Boolean a = Convert.ToBoolean(qq);
Console.WriteLine(a.ToString());
}
问题
所以我的问题是从 C# 中的 IntPtr 转换为 bool 数组的正确方法是什么?
最佳答案
… assigning
true
orfalse
to the pointer, back in C# I got theIntPtr
, and I used theIntPtr.ToPointer()
function and then just cast it into a byte …
这是错误的,即使它可能有效。如果返回类型是void*
,那么它实际上应该是一个指针,而不是一个 bool 值。如果你真的想执行这种暴行,那么你不需要使用指针的中间步骤,你可以将 IntPtr
直接转换为 byte
。
现在,回答您的实际问题:如果您知道该函数将始终返回两个 bool 值的数组,我认为最好在 C# 中使用适当的方法将其声明为返回 bool[]
属性(类似于 [return: MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagementType.I1, SizeConst=2)]
)。
但是您的 C# 代码也应该可以工作。我认为问题出在您的 C 代码中:您返回的数组被声明为 vpointer*
,根据您的评论,它相当于 void**
。这意味着在 32 位机器上,C 编译器将此变量视为 4 字节值的数组。如果您希望它将其视为 1 字节值的数组,则需要这样声明(例如 boolean *chromosome;
)。
关于c# - 如何在 C# 中将 IntPtr 转换为 Boolean[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12444654/