"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como acessar campos de união no CGo do Go?

Como acessar campos de união no CGo do Go?

Publicado em 2024-11-06
Navegar:298

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

Convertendo campos de união em tipos Go em Golang CGo

Ao trabalhar com estruturas C em Golang CGo, acessar campos de união pode ser um desafio. Um cenário comum envolve acessar o campo ui32v em uma união de valores dentro de uma estrutura C, como no exemplo a seguir:

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 */
};

Nota: Neste exemplo, estamos em uma plataforma de 64 bits.

Abordagem falhada: conversão para uint64 e transmissão

Uma abordagem inicial pode envolver a conversão do conteúdo do campo de união em um uint64, assumindo que ele representa um endereço de memória e, em seguida, convertendo esse uint64 em um *_Ctype_guint32. No entanto, esta abordagem resultará em um erro de conversão de tipo.

Abordagem correta: usando o endereço da União

Em vez disso, a abordagem correta envolve usar o endereço do próprio sindicato. No CGo, uma união é exposta como uma matriz de bytes grande o suficiente para conter seu maior membro. Nesse caso, essa matriz tem oito bytes ([8]byte). Usando o endereço deste array, podemos convertê-lo diretamente para o tipo desejado.

Para dados nomeados C._GNetSnmpVarBind, o código a seguir demonstra esta abordagem:

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

Detalhamento do Código:

  • &data. value[0] obtém o endereço do primeiro byte na união de valores.
  • unsafe.Pointer(&data.value[0]) converte esse endereço em um ponteiro do tipo unsafe.Pointer.
  • (**C.guint32)(unsafe.Pointer(&data.value[0])) interpreta a memória apontada por unsafe.Pointer(&data.value[0]) como um **C.guint32, acessando efetivamente o ui32v field como um ponteiro para um guint32.

Essa abordagem simplificada permite acesso direto a campos de união no código Go.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3