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!