title: Golang CGo: converting union field to Go type
body: <p>I'm working with this C struct on a 64 bit platform, trying to access the <strong>ui32v</strong> field in the <strong>value</strong> union:</p>
  
  <pre><code>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></pre>
  
  <p>I could write a C wrapper function for each union element but for didactic purposes I'd rather work in Go. Here's how I'm trying to access the <strong>ui32v</strong> field:</p>
  
  <pre><code>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></pre>
  
  <p>However this gives an error <strong>cannot convert ptr (type uint64) to type unsafe.Pointer</strong></p>
  
  <p>So how <em>do</em> I convert a <strong>uint64</strong> to a Go type that points to a C guint32? I've tried various combinations of casting to a uintptr then casting to a *_Ctype_guint32, casting to a uintptr then using unsafe.Pointer, ...</p>
  
  <p>My reasoning is: I'm passed an array of 8 bytes. Convert that to a uint64, that's the memory address. Cast that to a pointer to a guint32 (ie a C array of guint32's), and return that as a result - that is the union field "value" as a guint32 *.</p>
  
  <hr>
  
  <p><strong>Context</strong></p>
  
  <p>Later I'll want to convert the C array of guint32's to a string utilising the value_len field, using a function I know already works:</p>
  
  <pre><code>guint32_star := union_to_guint32_ptr(data.value)
  result += OidArrayToString(guint32_star, data.value_len)
  </code></pre>
  
  <p>The C code is from <a href="http://sourcecodebrowser.com/gsnmp/0.3.0/annotated.html">gsnmp</a>.</p>