>백엔드 개발 >Golang >Go v1.6 이후 cgo를 사용하여 C 코드에 함수 포인터를 전달하는 방법은 무엇입니까?

Go v1.6 이후 cgo를 사용하여 C 코드에 함수 포인터를 전달하는 방법은 무엇입니까?

Linda Hamilton
Linda Hamilton원래의
2024-11-01 11:35:29279검색

How to Pass Function Pointers to C Code Using cgo After Go v1.6?

cgo를 사용하여 C 코드에 함수 포인터 전달

Go v1.6 이전에는 cgo에서 Go 포인터를 C 코드에 전달할 수 있었습니다. 그러나 v1.6에서 변경 사항이 구현된 후 포인터 전달 규칙이 크게 변경되었습니다. 이 변경으로 인해 이전에 C 코드에서 동적 Go 콜백을 호출하는 데 사용된 방법이 무효화되었습니다.

문제 설명

Go 콜백 호출의 기능적 예인 코드 샘플 C에서 실행하면 이제 런타임 오류가 발생합니다.

panic: runtime error: cgo argument has Go pointer to Go pointer

솔루션

새로운 cgo 규칙에 따라 Go 코드는 다음과 같은 경우에만 Go 포인터를 C에 전달할 수 있습니다. 그것이 가리키는 Go 메모리에는 Go 포인터가 포함되어 있지 않습니다. 이 제한은 포인티드 메모리가 Go 함수/메서드 포인터를 저장하는 경우 C 코드에 포인터를 전달하는 것을 방지합니다.

이 제한을 극복하기 위해 몇 가지 접근 방식을 고려할 수 있습니다. 일반적인 솔루션에는 특정 ID와 실제 포인터 간의 대응을 설정하는 동기화된 데이터 구조를 저장하는 것이 포함됩니다. 포인터 대신 C 코드에 ID를 전달하면 제한이 우회됩니다.

이 솔루션을 보여주는 업데이트된 코드 샘플:

<code class="go">package gocallback

import (
    "fmt"
    "sync"
)

/*
extern void go_callback_int(int foo, int p1);
*/
import "C"

var mu sync.Mutex
var index int
var fns = make(map[int]func(C.int))

func register(fn func(C.int)) int {
    mu.Lock()
    defer mu.Unlock()
    index++
    for fns[index] != nil {
        index++
    }
    fns[index] = fn
    return index
}

func lookup(i int) func(C.int) {
    mu.Lock()
    defer mu.Unlock()
    return fns[i]
}

func unregister(i int) {
    mu.Lock()
    defer mu.Unlock()
    delete(fns, i)
}

//export go_callback_int
func go_callback_int(foo C.int, p1 C.int) {
    fn := lookup(int(foo))
    fn(p1)
}

func MyCallback(x C.int) {
    fmt.Println("callback with", x)
}

func Example() {
    i := register(MyCallback)
    C.go_callback_int(C.int(i), 5)
    unregister(i)
}

func main() {
    Example()
}</code>

이 솔루션은 업데이트된 Wiki 페이지를 따르며, 현재 cgo 제약 조건 내에서 C 코드에 함수 포인터를 전달하는 강력한 접근 방식입니다.

위 내용은 Go v1.6 이후 cgo를 사용하여 C 코드에 함수 포인터를 전달하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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