„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Wie greife ich in Go's CGo auf Union-Felder zu?

Wie greife ich in Go's CGo auf Union-Felder zu?

Veröffentlicht am 06.11.2024
Durchsuche:341

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

Konvertieren von Union-Feldern in Go-Typen in Golang CGo

Bei der Arbeit mit C-Strukturen in Golang CGo kann der Zugriff auf Union-Felder eine Herausforderung sein. Ein häufiges Szenario beinhaltet den Zugriff auf das ui32v-Feld in einer Werteunion innerhalb einer C-Struktur, wie im folgenden Beispiel:

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 */
};

Hinweis: In diesem Beispiel befinden wir uns auf einer 64-Bit-Plattform.

Fehlgeschlagener Ansatz: Konvertierung in uint64 und Casting

Ein erster Ansatz könnte darin bestehen, den Inhalt des Union-Felds in einen uint64-Wert zu konvertieren, vorausgesetzt, er stellt eine Speicheradresse dar, und diesen uint64-Wert dann in einen *_Ctype_guint32-Wert umzuwandeln. Dieser Ansatz führt jedoch zu einem Typkonvertierungsfehler.

Richtiger Ansatz: Verwendung der Adresse der Union

Der richtige Ansatz besteht stattdessen darin, die Adresse der Union zu verwenden Gewerkschaft selbst. In CGo wird eine Union als Byte-Array bereitgestellt, das groß genug ist, um sein größtes Mitglied aufzunehmen. In diesem Fall umfasst dieses Array acht Bytes ([8]Byte). Indem wir die Adresse dieses Arrays verwenden, können wir es direkt in den gewünschten Typ umwandeln.

Für benannte C._GNetSnmpVarBind-Daten demonstriert der folgende Code diesen Ansatz:

guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))

Aufschlüsselung des Codes:

  • &data. value[0] erhält die Adresse des ersten Bytes in der Wertvereinigung.
  • unsafe.Pointer(&data.value[0]) wandelt diese Adresse in einen Zeiger vom Typ unsafe.Pointer.
  • (**C.guint32)(unsafe.Pointer(&data.value[0])) interpretiert den Speicher, auf den unsafe.Pointer(&data.value[0]) zeigt, als **C.guint32 und greift effektiv auf ui32v zu Feld als Zeiger auf ein guint32.

Dieser vereinfachte Ansatz ermöglicht den direkten Zugriff auf Union-Felder im Go-Code.

Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3