Maison >développement back-end >Golang >Comment convertir un champ Union C en un type Go dans Golang CGo ?

Comment convertir un champ Union C en un type Go dans Golang CGo ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-01 13:58:02874parcourir

How to Convert a C Union Field to a Go Type in Golang CGo?

Golang CGo : Conversion du champ Union en type Go

Énoncé du problème

En C, une union permet à plusieurs données membres d'occuper le même emplacement mémoire . Lorsque vous travaillez avec des unions en CGo, il est souvent nécessaire de convertir le champ union en un type Go approprié pour un traitement ultérieur.

Considérez la structure C suivante avec une union :

<code class="c">struct _GNetSnmpVarBind {
  ...
  union {
    gint32   i32;           /* 32 bit signed   */
    guint32  ui32;          /* 32 bit unsigned */
    ...
  }         value;      /* value of the variable */
  ...
};</code>

Supposons vous souhaitez accéder au champ ui32v dans l'union de valeurs sur une plate-forme 64 bits.

Solution

Normalement, on écrirait une fonction wrapper C pour chaque élément de l'union. Cependant, à des fins éducatives, explorons comment le faire dans Go.

Conversion de CGo Union Array en Go Pointer

Initialement, l'union est exposée comme un Go Pointer. tableau d'octets [8]octet. Le but est de convertir ce tableau en un type Go qui pointe vers le tableau C guint32.

Traditionnellement, cela peut être fait comme suit :

<code class="go">func union_to_guint32_ptr(cbytes [8]byte) (result *_Ctype_guint32) {
  buf := bytes.NewBuffer(cbytes[:])
  var ptr uint64
  if err := binary.Read(buf, binary.LittleEndian, &amp;ptr); err == nil {
    return (*_Ctype_guint32)(unsafe.Pointer(ptr))
  }
  return nil
}</code>

Cette approche rencontre cependant un erreur de conversion entre uint64 (le résultat de binaire.Read) et unsafe.Pointer.

Méthode de conversion simplifiée

Une solution plus simple consiste à utiliser l'adresse de l'octet tableau lui-même, qui est un pointeur vers l'emplacement mémoire du champ d'union :

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

Cette technique traduit efficacement l'adresse du tableau d'octets en un pointeur vers le type C souhaité, évitant ainsi le besoin de conversions intermédiaires.

Utilisation en conjonction avec des fonctionnalités existantes

Ce pointeur peut ensuite être utilisé en conjonction avec des fonctionnalités existantes, telles que la conversion d'un tableau C de guint32 en chaîne :

<code class="go">guint32_star := union_to_guint32_ptr(data.value)
result += OidArrayToString(guint32_star, data.value_len)</code>

Cette approche simplifie grandement l'accès et la manipulation des champs syndicaux dans les applications Golang CGo.

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