Сопоставить структуру 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
}