"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Comment accéder aux champs Union dans le CGo de Go ?

Comment accéder aux champs Union dans le CGo de Go ?

Publié le 2024-11-06
Parcourir:400

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

Conversion des champs Union en types Go dans Golang CGo

Lorsque vous travaillez avec des structures C dans Golang CGo, l'accès aux champs union peut être un défi. Un scénario courant implique l'accès au champ ui32v dans une union de valeurs au sein d'une structure C, comme dans l'exemple suivant :

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

Remarque : Dans cet exemple, nous sommes sur une plate-forme 64 bits.

Approche échouée : conversion en uint64 et diffusion

Une approche initiale pourrait impliquer de convertir le contenu du champ union en un uint64, en supposant qu'il représente une adresse mémoire, puis de convertir cet uint64 en *_Ctype_guint32. Cependant, cette approche entraînera une erreur de conversion de type.

Approche correcte : utiliser l'adresse de l'Union

Au lieu de cela, l'approche correcte implique d'utiliser l'adresse de l'Union. syndicat lui-même. Dans CGo, une union est exposée sous la forme d'un tableau d'octets suffisamment grand pour contenir son plus grand membre. Dans ce cas, ce tableau fait huit octets ([8]byte). En utilisant l'adresse de ce tableau, nous pouvons le convertir directement dans le type souhaité.

Pour une donnée nommée C._GNetSnmpVarBind, le code suivant illustre cette approche :

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

Détail du Code :

  • &data. value[0] obtient l'adresse du premier octet de l'union de valeurs.
  • unsafe.Pointer(&data.value[0]) convertit cette adresse en un pointeur de type unsafe.Pointer.
  • (**C.guint32)(unsafe.Pointer(&data.value[0])) interprète la mémoire pointée par unsafe.Pointer(&data.value[0]) comme un **C.guint32, accédant efficacement à l'ui32v champ comme pointeur vers un guint32.

Cette approche simplifiée permet un accès direct aux champs d'union dans le code Go.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3