gpt4 book ai didi

c# - 当结构包含 bool 时如何将 GCHandle 分配给结构

转载 作者:可可西里 更新时间:2023-11-01 08:57:30 25 4
gpt4 key购买 nike

我一直在尝试创建一个结构类型的句柄,因为我需要一个指向它的固定指针,但我收到错误“对象包含非原始数据或非 blittable 数据”

我的结构是这样的:

[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.U1)]
public bool Test;
}

现在,当我打电话时,

var mystruct = new MyStruct();
var handle = GCHandle.Alloc(mystruct, GCHandleType.Pinned);

我收到错误“对象包含非原始数据或不可 blittable 数据”。现在我明白了 bool 字段是一个 non-blittable 类型。但我的印象是,通过添加 MarshalAs 属性,我可以告诉编码器如何转换类型。 (我也试过 UnmanagedType.Bool)

这个结构必须全局定义,因为我的整个类(class)都需要它。我需要指针的唯一原因是因为我有一个非托管 API,它必须将此结构作为指针传递。然后我必须在回调中获取该结构并读取/更新成员。

这是基本场景。

  1. 结构在托管类中全局创建
  2. 获得指向结构的指针
  3. 指向结构的指针被传递到 API 中
  4. API 调用一个静态方法回调,然后我需要在其中获取我的结构并读取/更新成员。

我尝试使用 Marshal.StructureToPtr 但这只会创建一个副本,因此如果在我的托管类中更新成员,当引发回调时,更新的值不存在。

有谁知道我如何获得指向我的结构的固定指针,以便我可以读取/修改公共(public)成员并让它们在回调中可用?

谢谢

最佳答案

您遇到的问题不止一个。使用 struct 是非常不可取的。它会在 GCHandle.Alloc() 调用之前被装箱,那个装箱的对象被固定。您无法通过 mystruct 变量看到任何更新。请改用

并避免 bool,由于其高度可变的实现,它是一种不可 blittable 的类型。在 C 中为 4 个字节,在 C++ 中为 1 个字节,在 COM 中为 2 个字节。只需将其设为 byte 即可。您可以编写属性以将其恢复为 bool 值。

所以:

[StructLayout(LayoutKind.Sequential)]
public class MyStruct
{
private byte _test;
public bool Test {
get { return _test != 0; }
set { _test = value ? 1 : 0; }
}
}

关于c# - 当结构包含 bool 时如何将 GCHandle 分配给结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27670811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com