「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Go の CGo でユニオン フィールドにアクセスするにはどうすればよいですか?

Go の CGo でユニオン フィールドにアクセスするにはどうすればよいですか?

2024 年 11 月 6 日に公開
ブラウズ:671

How to Access Union Fields in Go\'s CGo?

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.

    unsafe.Pointer(&data.value[0]) は、このアドレスを unsafe.Pointer 型のポインタに変換します。
  • (**C.guint32)(unsafe.Pointer(&data.value[0])) は、unsafe.Pointer(&data.value[0]) が指すメモリを **C.guint32 として解釈し、実質的に ui32v にアクセスします。フィールドを guint32 へのポインターとして使用します。
  • この簡素化されたアプローチにより、Go コード内の共用体フィールドに直接アクセスできます。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3