«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как получить доступ к полям объединения в CGo Go?

Как получить доступ к полям объединения в CGo Go?

Опубликовано 6 ноября 2024 г.
Просматривать:605

How to Access Union Fields in Go\'s CGo?

Преобразование полей объединения в типы Go в Golang CGo

При работе со структурами C в Golang CGo доступ к полям объединения может стать проблемой. Обычный сценарий предполагает доступ к полю ui32v в объединении значений внутри структуры C, как в следующем примере:

struct _GNetSnmpVarBind {
  guint32       *oid;       /* name of the variable */
  gsize     oid_len;    /* length of the name */
  GNetSnmpVarBindType   type;       /* variable type / exception */
  union {
    gint32   i32;           /* 32 bit signed   */
    guint32  ui32;          /* 32 bit unsigned */
    gint64   i64;           /* 64 bit signed   */
    guint64  ui64;          /* 64 bit unsigned */
    guint8  *ui8v;          /*  8 bit unsigned vector */
    guint32 *ui32v;         /* 32 bit unsigned vector */
  }         value;      /* value of the variable */
  gsize     value_len;  /* length of a vector in bytes */
};

Примечание: В этом примере мы работаем на 64-битной платформе.

Неудачный подход: преобразование в uint64 и приведение типов

Первоначальный подход может включать преобразование содержимого поля объединения в uint64, предполагая, что оно представляет адрес памяти, а затем преобразование этого uint64 в *_Ctype_guint32. Однако такой подход приведет к ошибке преобразования типа.

Правильный подход: использование адреса объединения

Вместо этого правильный подход предполагает использование адреса объединения. сам союз. В CGo объединение представляется как массив байтов, достаточно большой, чтобы вместить его самый большой член. В данном случае этот массив состоит из восьми байтов ([8]байт). Используя адрес этого массива, мы можем напрямую привести его к нужному типу.

Для именованных данных C._GNetSnmpVarBind следующий код демонстрирует этот подход:

guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))

Разбивка кода:

  • &data. value[0] получает адрес первого байта в объединении значений.
  • unsafe.Pointer(&data.value[0]) преобразует этот адрес в указатель типа unsafe.Pointer.
  • (**C.guint32)(unsafe.Pointer(&data.value[0])) интерпретирует память, на которую указывает unsafe.Pointer(&data.value[0]) как **C.guint32, эффективно обращаясь к ui32v поле как указатель на guint32.

Этот упрощенный подход обеспечивает прямой доступ к полям объединения в коде Go.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3