>백엔드 개발 >Golang >CGo에서 C 공용체 필드를 Go 유형으로 어떻게 변환합니까?

CGo에서 C 공용체 필드를 Go 유형으로 어떻게 변환합니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-03 01:38:02658검색

How do you convert a C union field to a Go type in CGo?

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

Go의 CGo에서 C Union은 Union의 크기에 따라 결정되는 바이트 배열로 표현됩니다. 가장 큰 회원. 이를 통해 Union의 콘텐츠에 직접 액세스할 수 있습니다. 그러나 공용체 필드를 Go 유형으로 변환하려면 포인터 작업이 필요합니다.

포인터 및 공용체 해석

공용체를 포함하는 다음 C 구조체를 고려하세요.

<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>

액세스하려면 Go의 ui32v 필드에서는 다음을 사용하여 바이트 배열을 포인터로 변환하려고 시도할 수 있습니다.

<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, &amp;ptr); err == nil {
    return (*_Ctype_guint32)(unsafe.Pointer(ptr))
  }
  return nil
}</code>

그러나 이 접근 방식은 유형 변환 문제로 인해 실패합니다. 이 문제를 해결하려면 바이트 배열의 주소를 포인터로 직접 사용할 수 있습니다.

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

이 작업은 바이트 배열의 첫 번째 요소 주소를 추출하여 공용체 자체의 주소를 효과적으로 얻습니다. unsafe.Pointer를 사용하여 포인터 유형을 조작함으로써 메모리를 원하는 유형(*C.guint32)에 대한 포인터로 재해석합니다. 마지막으로 결과를 역참조하면 공용체 멤버의 콘텐츠에 액세스할 수 있습니다.

CGo에서 공용체의 표현과 조작을 이해함으로써 개발자는 Go 프로그램에서 복잡한 C 데이터 구조를 효과적으로 작업할 수 있습니다.

위 내용은 CGo에서 C 공용체 필드를 Go 유형으로 어떻게 변환합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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