在 Golang CGo 中将 Union 字段转换为 Go 类型
在 Golang CGo 中使用 C 结构时,访问 union 字段可能是一个挑战。常见场景涉及访问 C 结构内值联合中的 ui32v 字段,如下例所示:
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 */
};
注意:在此示例中,我们在 64 位平台上。
失败的方法:转换为 uint64 并强制转换
最初的方法可能涉及将 union 字段的内容转换为 uint64,假设它表示内存地址,然后将该 uint64 转换为 *_Ctype_guint32。然而,这种方法会导致类型转换错误。
正确的方法:使用 Union 的地址
相反,正确的方法是使用 Union 的地址工会本身。在 CGo 中,联合被公开为一个足以容纳其最大成员的字节数组。在本例中,该数组为八个字节 ([8]byte)。通过使用该数组的地址,我们可以直接将其转换为所需的类型。
对于 C._GNetSnmpVarBind 命名数据,以下代码演示了这种方法:
guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))
代码细分:
这种简化的方法允许直接访问 Go 代码中的联合字段。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3