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, &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(&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 중국어 웹사이트의 기타 관련 기사를 참조하세요!