Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Menghantar Penunjuk Fungsi kepada Kod C Menggunakan cgo After Go v1.6?

Bagaimana untuk Menghantar Penunjuk Fungsi kepada Kod C Menggunakan cgo After Go v1.6?

Linda Hamilton
Linda Hamiltonasal
2024-11-01 11:35:29177semak imbas

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

Melalukan Penunjuk Fungsi kepada Kod C Menggunakan cgo

Sebelum Go v1.6, cgo membenarkan penghantaran penunjuk Go kepada kod C. Walau bagaimanapun, selepas perubahan dilaksanakan dalam v1.6, peraturan untuk menghantar penunjuk berubah dengan ketara. Pindaan ini menyebabkan kaedah yang digunakan sebelum ini untuk menggunakan panggilan balik Go dinamik daripada kod C tidak berkesan.

Penerangan Masalah

Sampel kod, sekali contoh berfungsi untuk memanggil balik Go daripada C, kini mengakibatkan ralat masa jalan:

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

Penyelesaian

Di bawah peraturan cgo baharu, kod Go boleh menghantar penuding Go kepada C hanya jika Memori Go yang ditunjuknya tidak mengandungi sebarang penunjuk Go. Sekatan ini menghalang penghantaran penuding kepada kod C jika memori yang ditunjuk menyimpan penunjuk fungsi/kaedah Go.

Untuk mengatasi had ini, beberapa pendekatan boleh dipertimbangkan. Penyelesaian biasa melibatkan penyimpanan struktur data yang disegerakkan yang mewujudkan kesesuaian antara ID tertentu dan penunjuk sebenar. Dengan menghantar ID kepada kod C dan bukannya penuding, sekatan akan dipintas.

Sampel kod dikemas kini yang mempamerkan penyelesaian ini:

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

Penyelesaian ini mengikuti halaman wiki yang dikemas kini, memberikan pendekatan yang mantap untuk menghantar penunjuk fungsi kepada kod C dalam kekangan cgo semasa.

Atas ialah kandungan terperinci Bagaimana untuk Menghantar Penunjuk Fungsi kepada Kod C Menggunakan cgo After Go v1.6?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn