如何在 C# 中使用 struct 和 union

发布于 2024-12-13 19:05:42 字数 1829 浏览 0 评论 0原文

您好,我用 C# 编写了一个包装器,但遇到了一些问题。我在 C++ 中有这个结构。

typedef struct pjmedia_format
{
    pj_uint32_t id;
    pjmedia_type type;
    pjmedia_format_detail_type detail_type;
    union
    {
    pjmedia_audio_format_detail aud;
    pjmedia_video_format_detail vid;
    char user[PJMEDIA_FORMAT_DETAIL_USER_SIZE];
    } det;
} pjmedia_format;

结构 pjmedia_format 的链接

这是c#中 我有这个:

[StructLayout(LayoutKind.Sequential)]
public struct pjmedia_format
{
    public uint id;
    public pjmedia_type type;
    public pjmedia_format_detail_type detail_type;
    public det_t det;
}

[StructLayout(LayoutKind.Explicit)]
public struct det_t
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_audio_format_detail aud;
    [FieldOffset(36)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_video_format_detail vid;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    [FieldOffset(60)]
    public char[] user;
}

[StructLayout(LayoutKind.Sequential)]
public struct pjmedia_audio_format_detail
{
    public uint clock_rate;
    public uint channel_count;
    public uint frame_time_usec;
    public uint bits_per_sample;
    public int avg_bps;
    public int max_bps;
}

[StructLayout(LayoutKind.Sequential)]
public struct pjmedia_video_format_detail
{
    public pjmedia_rect_size size;
    public pjmedia_ratio fps;
    public int avg_bps;
    public int max_bps;
}

当我想使用这个结构时,我收到这个错误

System.Runtime.InteropServices.MarshalDirectiveException 未处理。 Message="方法签名与元素不兼容。"

我尝试使用一些属性,例如尺寸或包装,但它没有帮助(可能我使用错误)。我单独测试了其他结构,例如 pjmedia_video_format_detail,它们运行良好。有什么建议吗?

此致 安杰伊

Hi I writing a wrapper in c# and i have some problem. I have this struct in c++.

typedef struct pjmedia_format
{
    pj_uint32_t id;
    pjmedia_type type;
    pjmedia_format_detail_type detail_type;
    union
    {
    pjmedia_audio_format_detail aud;
    pjmedia_video_format_detail vid;
    char user[PJMEDIA_FORMAT_DETAIL_USER_SIZE];
    } det;
} pjmedia_format;

This is link to this struct pjmedia_format

in c# I have this:

[StructLayout(LayoutKind.Sequential)]
public struct pjmedia_format
{
    public uint id;
    public pjmedia_type type;
    public pjmedia_format_detail_type detail_type;
    public det_t det;
}

[StructLayout(LayoutKind.Explicit)]
public struct det_t
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_audio_format_detail aud;
    [FieldOffset(36)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_video_format_detail vid;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    [FieldOffset(60)]
    public char[] user;
}

[StructLayout(LayoutKind.Sequential)]
public struct pjmedia_audio_format_detail
{
    public uint clock_rate;
    public uint channel_count;
    public uint frame_time_usec;
    public uint bits_per_sample;
    public int avg_bps;
    public int max_bps;
}

[StructLayout(LayoutKind.Sequential)]
public struct pjmedia_video_format_detail
{
    public pjmedia_rect_size size;
    public pjmedia_ratio fps;
    public int avg_bps;
    public int max_bps;
}

and when i want to use this struct i get this error

System.Runtime.InteropServices.MarshalDirectiveException was unhandled.
Message="A method signature is not PInvoke compatible with the element."

I try to use some attributes like size or pack but it doesn't help (probably i use it wrong). I tested singly other struct e.g. pjmedia_video_format_detail and they works well. Any advice?

Best regards
Andrzej

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

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

发布评论

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

评论(2

遮云壑 2024-12-20 19:05:42

由于这是一个联合,因此不应该是:

[StructLayout(LayoutKind.Explicit)]
public struct det_t
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_audio_format_detail aud;
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_video_format_detail vid;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    [FieldOffset(0)]
    public char[] user;
}

即重叠吗? 此外,您可能需要将user作为固定缓冲区而不是数组。

As this is a union, shouldn't that be:

[StructLayout(LayoutKind.Explicit)]
public struct det_t
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_audio_format_detail aud;
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.Struct)]
    public pjmedia_video_format_detail vid;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    [FieldOffset(0)]
    public char[] user;
}

i.e. overlapping? Also, you might need user to be a fixed buffer rather than an array.

只为守护你 2024-12-20 19:05:42

在 C++ 代码中,det 是一个联合。这意味着所有字段的偏移量为零,它们是重叠的。只需对 det_t 中的所有字段使用 [FieldOffset(0)] 更改 C# 声明即可匹配。

In the C++ code, det is a union. That means that all the fields have zero offset, they are overlayed. Simply change your C# declaration to match by using [FieldOffset(0)] for all fields in det_t.

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