C では、Union を使用すると複数のデータ メンバーが同じメモリ位置を占有することができます。 。 CGo で共用体を使用する場合、多くの場合、その後の処理のために共用体フィールドを適切な Go 型に変換する必要があります。
共用体を含む次の C 構造体を考えてみましょう。
<code class="c">struct _GNetSnmpVarBind { ... union { gint32 i32; /* 32 bit signed */ guint32 ui32; /* 32 bit unsigned */ ... } value; /* value of the variable */ ... };</code>
としましょう。 64 ビット プラットフォームで値共用体の ui32v フィールドにアクセスしたいとします。
通常、各共用体要素に対して C ラッパー関数を作成します。ただし、教育目的のため、Go でそれを行う方法を調べてみましょう。
CGo ユニオン配列から Go ポインターへの変換
最初は、ユニオンは Go として公開されます。バイト配列 [8] バイト。目標は、この配列を C の guint32 配列を指す Go 型に変換することです。
従来、これは次のように実行できます。
<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, &ptr); err == nil { return (*_Ctype_guint32)(unsafe.Pointer(ptr)) } return nil }</code>
ただし、このアプローチでは次のような問題が発生します。 uint64 (binary.Read の結果) と unsafe.Pointer.
簡易変換メソッド
間の変換エラー。より簡単な解決策は、バイトのアドレスを使用することです。配列自体 (共用体フィールドのメモリ位置へのポインタ):
<code class="go">guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))</code>
この手法は、バイト配列アドレスを目的の C 型へのポインタに効果的に変換し、中間変換の必要性を回避します。
このポインターは、guint32 の C 配列を文字列に変換するなど、既存の機能と組み合わせて使用できます。
<code class="go">guint32_star := union_to_guint32_ptr(data.value) result += OidArrayToString(guint32_star, data.value_len)</code>
このアプローチGolang CGo アプリケーションでの共用体フィールドへのアクセスと操作が大幅に簡素化されます。
以上がGolang CGo で C Union フィールドを Go 型に変換するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。