背景资料
我在C中有一个函数,它返回avoid*
。
我开始测试两个项目之间的转换,将true
或false
赋给指针,回到C中,我得到了IntPtr
,我使用了IntPtr.ToPointer()
函数,然后将它转换成一个字节,根据我所读的内容,这相当于C中的布尔值。
这对我很管用。
德林波特:
[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");
问题
当我试图做同样的事情,但是给指针分配一个布尔数组时,我还没能用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
函数,将指针复制到字节数组尽管这次我没有任何异常,但我没有得到正确的结果我的意思是,例如,如果数组的第一个布尔值为false,那么im将变为true。这就是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转换为布尔数组的正确方法是什么?
最佳答案
…将true
或false
赋给指针,回到C中,我得到了IntPtr
,使用了IntPtr.ToPointer()
函数,然后将其转换为一个字节…
那是错误的,即使它可能起作用了如果返回类型是void*
,那么它实际上应该是指针,而不是布尔值如果你真的想执行这个暴行,那么你不需要中间的指针步骤,你可以直接将IntPtr
转换成byte
。
现在,针对您的实际问题:如果您知道该函数将始终返回两个布尔值的数组,我认为最好将其声明为在C中返回带有适当属性的bool[]
(类似于[return: MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeConst=2)]
)。
但你的C代码也应该能工作我认为问题出在您的C代码中:您返回的数组声明为vpointer*
,根据您的注释,它相当于void**
这意味着在32位计算机上,C编译器将此变量视为4字节值数组如果您希望它将其视为1字节值数组,则需要将其声明为1字节值数组(例如boolean *chromosome;
)。
关于c# - 如何在C#中将IntPtr转换为Boolean []?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12444654/