Сопоставить структуру C с объединенным полем для структуры Go - PullRequest
0 голосов
/ 20 мая 2018

Я получаю результаты 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 Ответ

0 голосов
/ 21 мая 2018

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

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

Может быть, вам стоит попробовать это

type SPC_LINK struct {
    dwLinkChoice  DWORD
    dwLink        [{size of the union}]byte
}
...