c# - 如何在 C# 中将 IntPtr 转换为 Boolean[]?

标签 c# c arrays marshalling intptr

背景信息

我有一个 C 函数,它返回一个 void*

我开始测试两个项目之间的转换,将 truefalse 分配给指针,回到 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 or false to the pointer, back in C# I got the IntPtr, and I used the IntPtr.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/

相关文章:

c# - 为什么这种转换在 Powershell 中不能像在 C# 中那样工作?

do while 第一次后无法输入

c - AVR IO 端口不能是全局的

一次为多个用户提供 PHP $_SESSION

javascript - lodash 深度嵌套数组过滤器

arrays - ruby 创建对象随机次数

c# - 如何从多个类库中引用配置信息?

C# 正则表达式 - 替换为自身

c - 在C中返回一个 "static char[]"的字符串好不好?

c# - iTextSharp : PDF Gradient from Spot1 to Spot2