"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Go의 CGo에서 Union 필드에 어떻게 접근하나요?

Go의 CGo에서 Union 필드에 어떻게 접근하나요?

2024-11-06에 게시됨
검색:818

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

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

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

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]바이트)입니다. 이 배열의 주소를 사용하여 원하는 유형으로 직접 캐스팅할 수 있습니다.

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

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