Maison  >  Article  >  développement back-end  >  Comment accéder aux champs Union dans le CGo de Go ?

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

DDD
DDDoriginal
2024-11-01 07:45:02733parcourir

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, accéder aux champs union peut être un défi. Un scénario courant implique d'accéder au champ ui32v dans une union de valeurs au sein d'une structure C, comme dans l'exemple suivant :

<code class="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 */
};</code>

Remarque : Dans cet exemple, nous sommes sur un 64- plate-forme bit.

Approche échouée : conversion en uint64 et conversion

Une approche initiale peut impliquer la conversion du contenu du champ union en uint64, en supposant qu'il représente une adresse mémoire, puis convertissez 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 :

<code class="go">guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))</code>

Décomposition 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]) en tant que **C.guint32, accédant efficacement au champ ui32v en tant que pointeur vers un guint32.

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn