>백엔드 개발 >Golang >Golang CGo에서 C Union 필드를 Go 유형으로 변환하는 방법은 무엇입니까?

Golang CGo에서 C Union 필드를 Go 유형으로 변환하는 방법은 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-01 13:58:02877검색

How to Convert a C Union Field to a Go Type in Golang CGo?

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

문제 설명

C에서 공용체는 여러 데이터 멤버가 동일한 메모리 위치를 차지하도록 허용합니다. . 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비트 플랫폼에서 값 Union의 ui32v 필드에 액세스하려고 합니다.

해결책

일반적으로 각 Union 요소에 대해 C 래퍼 함수를 ​​작성합니다. 그러나 교육 목적으로 Go에서 이를 수행하는 방법을 살펴보겠습니다.

CGo Union Array에서 Go 포인터로 변환

처음에는 Union이 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, &amp;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(&amp;data.value[0]))</code>

이 기술은 중간 변환의 필요성을 우회하여 바이트 배열 주소를 원하는 C 유형에 대한 포인터로 효과적으로 변환합니다.

기존 기능과 함께 사용

이 포인터는 guint32s의 C 배열을 문자열로 변환하는 등 기존 기능과 함께 사용할 수 있습니다.

<code class="go">guint32_star := union_to_guint32_ptr(data.value)
result += OidArrayToString(guint32_star, data.value_len)</code>

이 접근 방식 Golang CGo 애플리케이션에서 Union 필드 액세스 및 조작을 크게 단순화합니다.

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

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