Сопоставить структуру C с объединенным полем для структуры Go

Я получаю результаты от syscall до некоторых WinApi в Go. Я легко сопоставляю простые структуры из кода C, но как справиться с такими структурами C, как показано ниже?

typedef struct SPC_LINK_
{
    DWORD dwLinkChoice;
#               define          SPC_URL_LINK_CHOICE         1
#               define          SPC_MONIKER_LINK_CHOICE     2
#               define          SPC_FILE_LINK_CHOICE        3

    union
    {
        LPWSTR                  pwszUrl;
        SPC_SERIALIZED_OBJECT   Moniker;
        LPWSTR                  pwszFile;
    };

} SPC_LINK, *PSPC_LINK;

Если все возможные типы определены в Go

type SPC_LINK struct {
    dwLinkChoice  DWORD
    Moniker       SPC_SERIALIZED_OBJECT
    pwszFile      LPWSTR
    pwszUrl       LPWSTR
}

после системного вызова с unsafe.Pointer к этой структуре Go в качестве параметра, я получил ее в памяти и могу получить к ней доступ в Go как обычно, но только первое поле после dwLinkChoice (Moniker в приведенном выше коде) всегда заполняется, остальные два всегда пусты. Я знаю, что это ожидаемое поведение в C, так как вы можете иметь только одно поле объединения за раз. Принимая это во внимание, должен ли я игнорировать всю структуру объединения и иметь какую-то метку-заполнитель в моей структуре Go?

type SPC_LINK struct {
    dwLinkChoice  DWORD
    dwLink        uintptr // a placeholder, will hold any possible value
}

Я установил тип для заполнителя в uintptr, но что если исходная структура C имеет некоторые другие не указательные типы в блоке объединения? Я действительно не уверен, как обращаться с профсоюзами C и искать какие-либо предложения.

1 ответ

Решение

Как указано в документации cgo,

Поскольку Go не поддерживает тип объединения C в общем случае, типы объединения C представляются в виде байтового массива Go одинаковой длины.

Может быть, вы должны попробовать это

type SPC_LINK struct {
    dwLinkChoice  DWORD
    dwLink        [{size of the union}]byte
}
Другие вопросы по тегам