Как использовать struct с union в c # - PullRequest
3 голосов
/ 04 ноября 2011

Привет, я пишу обертку в 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 = "Подпись метода не совместима с PInvoke с элементом."

Я пытаюсь использовать некоторые атрибуты, такие как размер или пакет, но это не помогает (возможно, я использую это неправильно). Я тестировал отдельно другую структуру, например pjmedia_video_format_detail и они работают хорошо. Любой совет?

С наилучшими пожеланиями Andrzej

Ответы [ 2 ]

2 голосов
/ 04 ноября 2011

Поскольку это союз, не должно ли это быть:

[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, чтобы быть фиксированным буфером , а не массивом.

1 голос
/ 04 ноября 2011

В коде C ++ det - это union .Это означает, что все поля имеют нулевое смещение, они наложены.Просто измените свою декларацию C # для соответствия, используя [FieldOffset(0)] для всех полей в det_t.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...