Golang CGo でユニオン フィールドを Go 型に変換する
Golang CGo で C 構造体を操作する場合、ユニオン フィールドにアクセスするのが難しい場合があります。一般的なシナリオには、次の例のように、C 構造体内の値共用体の ui32v フィールドへのアクセスが含まれます。 guint32 *oid; /* 変数の名前 */ gsize oid_len; /* 名前の長さ */ GNetSnmpVarBindType タイプ。 /* 変数の型 / 例外 */ 結合 { gint32 i32; /* 32 ビット符号付き */ guint32 ui32; /* 32 ビット符号なし */ gint64 i64; /* 64 ビット署名付き */ guint64 ui64; /* 64 ビット符号なし */ guint8 *ui8v; /* 8 ビット符号なしベクトル */ guint32 *ui32v; /* 32 ビット符号なしベクトル */ } 価値; /* 変数の値 */ gsize 値_len; /* ベクトルのバイト長 */ };
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 への変換とキャスト
最初のアプローチでは、共用体フィールドの内容をメモリ アドレスを表すものとして uint64 に変換し、その uint64 を *_Ctype_guint32 にキャストすることが考えられます。ただし、この方法では型変換エラーが発生します。
正しい方法: 共用体のアドレスを使用する
代わりに、正しい方法では、共用体のアドレスを使用します。組合そのもの。 CGo では、共用体は最大のメンバーを保持するのに十分な大きさのバイト配列として公開されます。この場合、その配列は 8 バイト ([8]byte) です。この配列のアドレスを使用すると、目的の型に直接キャストできます。
C._GNetSnmpVarBind 名前付きデータの場合、次のコードはこのアプローチを示しています:guint32_star : = *(**C.guint32)(unsafe.Pointer(&data.value[0]))
guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))
&data。 value[0] は、値の最初のバイトのアドレスを取得します Union.
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3