>  기사  >  백엔드 개발  >  Go의 CGo에서 Union 필드에 액세스하는 방법은 무엇입니까?

Go의 CGo에서 Union 필드에 액세스하는 방법은 무엇입니까?

DDD
DDD원래의
2024-11-01 07:45:02733검색

How to Access Union Fields in Go's CGo?

Golang CGo에서 Union 필드를 Go 유형으로 변환

Golang CGo에서 C 구조로 작업할 때 Union 필드에 액세스하는 것이 어려울 수 있습니다. 일반적인 시나리오에는 다음 예와 같이 C 구조체 내 값 공용체의 ui32v 필드에 액세스하는 것이 포함됩니다.

<code class="c">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 */
};</code>

참고: 이 예에서는 64- 비트 플랫폼.

실패한 접근 방식: uint64로 변환 및 캐스팅

초기 접근 방식에는 공용체 필드의 내용을 uint64로 변환하는 작업이 포함될 수 있습니다. 이때 이것이 메모리 주소를 나타낸다고 가정합니다. 그런 다음 해당 uint64를 *_Ctype_guint32로 캐스팅합니다. 그러나 이 접근 방식은 유형 변환 오류를 발생시킵니다.

올바른 접근 방식: 연합 주소 사용

대신 올바른 접근 방식은 연합 주소를 사용하는 것입니다. 노조 그 자체. CGo에서 공용체는 가장 큰 멤버를 담을 수 있을 만큼 큰 바이트 배열로 노출됩니다. 이 경우 해당 배열은 8바이트([8]바이트)입니다. 이 배열의 주소를 사용하여 원하는 유형으로 직접 캐스팅할 수 있습니다.

C._GNetSnmpVarBind 명명된 데이터의 경우 다음 코드는 이 접근 방식을 보여줍니다.

<code class="go">guint32_star := *(**C.guint32)(unsafe.Pointer(&data.value[0]))</code>

코드 분석:

  • &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로 사용하여 guint32에 대한 포인터로 ui32v 필드에 효과적으로 액세스합니다.

이 단순화된 접근 방식을 사용하면 Go 코드의 공용체 필드에 직접 액세스할 수 있습니다. .

위 내용은 Go의 CGo에서 Union 필드에 액세스하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.