खोज…
गो से C फंक्शन बुलाना
Cgo गो पैकेज बनाने में सक्षम बनाता है जो C कोड कहते हैं।
cgo
उपयोग करने के लिए सामान्य गो कोड लिखें जो एक छद्म पैकेज "सी" आयात करता है। गो कोड इसके बाद C.int
, या C.Add
जैसे फ़ंक्शन का उल्लेख कर सकता है।
"सी" का आयात तुरंत एक टिप्पणी से पहले होता है, उस टिप्पणी को, प्रस्तावना कहा जाता है, जिसका उपयोग पैकेज के सी भागों को संकलित करते समय हेडर के रूप में किया जाता है।
ध्यान दें कि cgo
टिप्पणी और आयात विवरण के बीच कोई रिक्त रेखाएं नहीं होनी चाहिए।
ध्यान दें कि import "C"
को अन्य आयात के साथ एक कोष्ठक, "तथ्यपूर्ण" आयात विवरण में वर्गीकृत नहीं किया जा सकता है। आपको कई आयात कथन लिखने होंगे, जैसे:
import "C"
import "fmt"
और यह अन्य आयात के लिए फैक्टरेड आयात विवरण का उपयोग करने के लिए अच्छी शैली है, जैसे:
import "C"
import (
"fmt"
"math"
)
सरल उदाहरण cgo
का उपयोग कर:
package main
//int Add(int a, int b){
// return a+b;
//}
import "C"
import "fmt"
func main() {
a := C.int(10)
b := C.int(20)
c := C.Add(a, b)
fmt.Println(c) // 30
}
फिर go build
, और इसे चलाएं, आउटपुट:
30
cgo
पैकेज बनाने के लिए, हमेशा की तरह go build
या go install
go build
उपयोग करें। go tool
विशेष "C"
आयात को पहचानता है और स्वचालित रूप से उन फाइलों के लिए cgo
का उपयोग करता है।
सभी दिशाओं में तार सी और गो कोड
गो से सी कोड कॉलिंग
package main
/*
// Everything in comments above the import "C" is C code and will be compiles with the GCC.
// Make sure you have a GCC installed.
int addInC(int a, int b) {
return a + b;
}
*/
import "C"
import "fmt"
func main() {
a := 3
b := 5
c := C.addInC(C.int(a), C.int(b))
fmt.Println("Add in C:", a, "+", b, "=", int(c))
}
C से गो कोड को कॉल करना
package main
/*
static inline int multiplyInGo(int a, int b) {
return go_multiply(a, b);
}
*/
import "C"
import (
"fmt"
)
func main() {
a := 3
b := 5
c := C.multiplyInGo(C.int(a), C.int(b))
fmt.Println("multiplyInGo:", a, "*", b, "=", int(c))
}
//export go_multiply
func go_multiply(a C.int, b C.int) C.int {
return a * b
}
फंक्शन पॉइंटर्स के साथ डील करना
package main
/*
int go_multiply(int a, int b);
typedef int (*multiply_f)(int a, int b);
multiply_f multiply;
static inline init() {
multiply = go_multiply;
}
static inline int multiplyWithFp(int a, int b) {
return multiply(a, b);
}
*/
import "C"
import (
"fmt"
)
func main() {
a := 3
b := 5
C.init(); // OR:
C.multiply = C.multiply_f(go_multiply);
c := C.multiplyWithFp(C.int(a), C.int(b))
fmt.Println("multiplyInGo:", a, "+", b, "=", int(c))
}
//export go_multiply
func go_multiply(a C.int, b C.int) C.int {
return a * b
}
कन्वर्ट प्रकार, पहुंच संरचना और सूचक अंकगणित
आधिकारिक गो प्रलेखन से:
// Go string to C string
// The C string is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CString(string) *C.char
// Go []byte slice to C array
// The C array is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CBytes([]byte) unsafe.Pointer
// C string to Go string
func C.GoString(*C.char) string
// C data with explicit length to Go string
func C.GoStringN(*C.char, C.int) string
// C data with explicit length to Go []byte
func C.GoBytes(unsafe.Pointer, C.int) []byte
इसका इस्तेमाल कैसे करें:
func go_handleData(data *C.uint8_t, length C.uint8_t) []byte {
return C.GoBytes(unsafe.Pointer(data), C.int(length))
}
// ...
goByteSlice := []byte {1, 2, 3}
goUnsafePointer := C.CBytes(goByteSlice)
cPointer := (*C.uint8_t)(goUnsafePointer)
// ...
func getPayload(packet *C.packet_t) []byte {
dataPtr := unsafe.Pointer(packet.data)
// Lets assume a 2 byte header before the payload.
payload := C.GoBytes(unsafe.Pointer(uintptr(dataPtr)+2), C.int(packet.dataLength-2))
return payload
}