"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > गो 1.6 और बाद में सीजीओ का उपयोग करके सी कोड में फ़ंक्शन पॉइंटर्स कैसे पास करें?

गो 1.6 और बाद में सीजीओ का उपयोग करके सी कोड में फ़ंक्शन पॉइंटर्स कैसे पास करें?

2024-11-09 को प्रकाशित
ब्राउज़ करें:125

How to Pass Function Pointers to C Code Using Cgo in Go 1.6 and Later?

Cgo का उपयोग करके फ़ंक्शन पॉइंटर को C कोड में पास करना

Cgo फ़ंक्शन पॉइंटर पासिंग में परिवर्तन

Go 1.6 और बाद में, Cgo में पासिंग के लिए सख्त नियम हैं सी कोड की ओर संकेत. अब किसी भी गो पॉइंटर वाले गो मेमोरी को इंगित करने वाले गो पॉइंटर को पास करने की अनुमति नहीं है।

कोड उदाहरण

निम्नलिखित गो कोड दर्शाता है कि फ़ंक्शन पॉइंटर को सी कोड में कैसे पास किया जाए:

import (
    "fmt"
    "unsafe"
)

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

   static inline void CallMyFunction(void* pfoo) {
       go_callback_int(pfoo, 5);
       }
*/
import "C"

//export go_callback_int
func go_callback_int(pfoo unsafe.Pointer, p1 C.int) {
    foo := *(*func(C.int))(pfoo)
    foo(p1)
}

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

// we store it in a global variable so that the garbage collector
// doesn't clean up the memory for any temporary variables created.
var MyCallbackFunc = MyCallback

func Example() {
    C.CallMyFunction(unsafe.Pointer(&MyCallbackFunc))
}

func main() {
    Example()
}

त्रुटि और समाधान

इस कोड को चलाने पर, यह एक त्रुटि उत्पन्न करता है क्योंकि MyCallbackFunc द्वारा इंगित गो मेमोरी में एक गो फ़ंक्शन पॉइंटर (MyCallback) होता है।

पता करने के लिए इसके लिए, हमें नए नियमों का उल्लंघन किए बिना फ़ंक्शन पॉइंटर को C कोड में पास करने का एक तरीका खोजने की आवश्यकता है।

पॉइंटर के बजाय एक आईडी का उपयोग करना

एक दृष्टिकोण है फ़ंक्शन पॉइंटर को सिंक्रोनाइज़्ड डेटा संरचना में संग्रहीत करने के लिए और डायरेक्ट पॉइंटर के बजाय सी कोड में एक आईडी पास करने के लिए। इस तरह, सी कोड डेटा संरचना के माध्यम से फ़ंक्शन पॉइंटर तक पहुंचने के लिए आईडी का उपयोग कर सकता है।

आईडी-आधारित फ़ंक्शन पॉइंटर पासिंग वाला कोड

package gocallback

import (
    "fmt"
    "sync"
)

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

static inline void CallMyFunction(int foo) {
    go_callback_int(foo, 5);
}
*/
import "C"

//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.CallMyFunction(C.int(i))
    unregister(i)
}

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)
}
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3