封送结构体同时保持其“非托管”状态

发布于 2024-08-19 21:34:06 字数 396 浏览 5 评论 0原文

我正在调用一个 DLL,该 DLL 返回一个结构指针的 void** 列表,所有指针的类型都相同。 根据我读过的内容,为了投射并获得我的如果结构不在该列表中,则该结构需要被视为非托管结构。我试图封送的结构的主要罪魁祸首是来自 C 端的以下两个字段:

char name[1024];
int crop[4];

大多数指南建议在托管端的相应结构上使用 string 或 int[],但是拥有这些字段使其成为托管结构,因此无法从 void** 列表中提取。

我可以通过什么方式封送这些字段来为我提供非托管结构?

I'm p-invoking into a DLL that returns a void** list of struct pointers, all of the same type. From what I've read, in order to cast and get my structure out of that list, the struct needs to be considered unmanaged. The main culprits to the struct I'm trying to marshal over are the following two fields from the C side:

char name[1024];
int crop[4];

Most guides suggest using string or int[] on the corresponding struct on the managed side, but that having those fields makes it into a managed struct and thus incapable of extracting from the void** list.

What's another way I can marshal these fields that gives me an unmanaged struct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

债姬 2024-08-26 21:34:06

如果您像这样声明结构,则无需帮助或不需要 unsafe 关键字即可对结构进行编组:

using System.Runtime.InteropServices;
...
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  public struct Example {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
    public string name;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    int[] crop;
  }

使用 Marshal.PtrToStructure() 将 void* 转换为结构。

The structure will marshal without help or need for the unsafe keyword if you declare it like this:

using System.Runtime.InteropServices;
...
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  public struct Example {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
    public string name;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    int[] crop;
  }

Convert the void* to the structure with Marshal.PtrToStructure().

故人的歌 2024-08-26 21:34:06

您可以使用 fixed 关键字创建固定大小的缓冲区数据结构中的数组:

unsafe struct Foo
{
    public fixed byte name[1024];
    public fixed int crop[4];
}

static unsafe void DumpCrops(void** ptr, int count)
{
    Foo** p = (Foo**)ptr;

    for (int i = 0; i < count; i++)
    {
        Foo* f = p[i];

        for (int j = 0; j < 4; j++)
        {
            Console.WriteLine(f->crop[j]);
        }
    }
}

You can use the fixed keyword to create a buffer with a fixed size array in a data structure:

unsafe struct Foo
{
    public fixed byte name[1024];
    public fixed int crop[4];
}

static unsafe void DumpCrops(void** ptr, int count)
{
    Foo** p = (Foo**)ptr;

    for (int i = 0; i < count; i++)
    {
        Foo* f = p[i];

        for (int j = 0; j < 4; j++)
        {
            Console.WriteLine(f->crop[j]);
        }
    }
}
愿与i 2024-08-26 21:34:06

您需要在结构上的该点添加一行,如图所示...

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct _FOOBAR {
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 1024, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I2)]
char name[1024];
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)]
int crop[4];
};

您需要仔细检查属性位 UnmanagedType 中的最后一位...

希望有帮助,
此致,
汤姆.

You need to add a line in that point on the struct as shown...

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct _FOOBAR {
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 1024, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I2)]
char name[1024];
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)]
int crop[4];
};

You need to double check on the last bit in the attribute bit, UnmanagedType...

Hope that helps,
Best regards,
Tom.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文