Zoeken…
Cgo: Eerste stappen tutorial
Enkele voorbeelden om de workflow van het gebruik van Go C-bindingen te begrijpen
Wat
In Go kunt u C-programma's en -functies oproepen met behulp van cgo . Op deze manier kunt u eenvoudig C-bindingen maken met andere toepassingen of bibliotheken die C API bieden.
Hoe
Het enige wat u hoeft te doen is om een import "C"
toe te voegen aan het begin van uw Go-programma, net nadat u uw C-programma hebt toegevoegd:
//#include <stdio.h> import "C"
Met het vorige voorbeeld kunt u het stdio
pakket in Go gebruiken.
Als u een app moet gebruiken die zich in dezelfde map bevindt, gebruikt u dezelfde syntaxis als in C (met de "
plaats van <>
)
//#include "hello.c" import "C"
BELANGRIJK : laat geen nieuwe regel tussen de
include
en deimport "C"
-instructies of u krijgt dit soort fouten bij het bouwen:
# command-line-arguments could not determine kind of name for C.Hello could not determine kind of name for C.sum
Het voorbeeld
In deze map vindt u een voorbeeld van C-bindingen. We hebben twee zeer eenvoudige C "bibliotheken" genaamd hello.c
:
//hello.c #include <stdio.h> void Hello(){ printf("Hello world\n"); }
Dat drukt gewoon "hallo wereld" af in de console en sum.c
//sum.c #include <stdio.h> int sum(int a, int b) { return a + b; }
... waarvoor 2 argumenten nodig zijn en de som wordt geretourneerd (niet afdrukken).
We hebben een main.go
programma dat gebruik zal maken van deze twee bestanden. Eerst importeren we ze zoals eerder vermeld:
//main.go package main /* #include "hello.c" #include "sum.c" */ import "C"
Hallo Wereld!
Nu zijn we klaar om de C-programma's in onze Go-app te gebruiken. Laten we eerst het Hello-programma proberen:
//main.go package main /* #include "hello.c" #include "sum.c" */ import "C" func main() { //Call to void function without params err := Hello() if err != nil { log.Fatal(err) } } //Hello is a C binding to the Hello World "C" program. As a Go user you could //use now the Hello function transparently without knowing that it is calling //a C function func Hello() error { _, err := C.Hello() //We ignore first result as it is a void function if err != nil { return errors.New("error calling Hello function: " + err.Error()) } return nil }
Voer nu het main.go-programma uit met behulp van go run main.go
om het C-programma af te drukken: "Hallo wereld!". Goed gedaan!
Som van int
Laten we het een beetje complexer maken door een functie toe te voegen die de twee argumenten samenvat.
//sum.c #include <stdio.h> int sum(int a, int b) { return a + b; }
En we noemen het vanuit onze vorige Go-app.
//main.go package main /* #include "hello.c" #include "sum.c" */ import "C" import ( "errors" "fmt" "log" ) func main() { //Call to void function without params err := Hello() if err != nil { log.Fatal(err) } //Call to int function with two params res, err := makeSum(5, 4) if err != nil { log.Fatal(err) } fmt.Printf("Sum of 5 + 4 is %d\n", res) } //Hello is a C binding to the Hello World "C" program. As a Go user you could //use now the Hello function transparently without knowing that is calling a C //function func Hello() error { _, err := C.Hello() //We ignore first result as it is a void function if err != nil { return errors.New("error calling Hello function: " + err.Error()) } return nil } //makeSum also is a C binding to make a sum. As before it returns a result and //an error. Look that we had to pass the Int values to C.int values before using //the function and cast the result back to a Go int value func makeSum(a, b int) (int, error) { //Convert Go ints to C ints aC := C.int(a) bC := C.int(b) sum, err := C.sum(aC, bC) if err != nil { return 0, errors.New("error calling Sum function: " + err.Error()) } //Convert C.int result to Go int res := int(sum) return res, nil }
Bekijk de functie "makeSum". Het ontvangt twee int
parameters die eerst moeten worden geconverteerd naar C int
met behulp van de C.int
functie. Ook zal de terugkeer van de oproep ons een C int
en een fout geven in het geval er iets mis is gegaan. We moeten C-respons op een Go's int uitbrengen met int()
.
Probeer onze go-app uit te voeren met go run main.go
$ go run main.go Hello world! Sum of 5 + 4 is 9
Een binair getal genereren
Als je een go-build probeert, kun je meerdere definitiefouten krijgen.
$ go build # github.com/sayden/c-bindings /tmp/go-build329491076/github.com/sayden/c-bindings/_obj/hello.o: In function `Hello': ../../go/src/github.com/sayden/c-bindings/hello.c:5: multiple definition of `Hello' /tmp/go-build329491076/github.com/sayden/c-bindings/_obj/main.cgo2.o:/home/mariocaster/go/src/github.com/sayden/c-bindings/hello.c:5: first defined here /tmp/go-build329491076/github.com/sayden/c-bindings/_obj/sum.o: In function `sum': ../../go/src/github.com/sayden/c-bindings/sum.c:5: multiple definition of `sum` /tmp/go-build329491076/github.com/sayden/c-bindings/_obj/main.cgo2.o:/home/mariocaster/go/src/github.com/sayden/c-bindings/sum.c:5: first defined here collect2: error: ld returned 1 exit status
De kunst is om direct naar het hoofdbestand te verwijzen wanneer je go build
:
$ go build main.go $ ./main Hello world! Sum of 5 + 4 is 9
Vergeet niet dat u een naam kunt
go build -o my_c_binding main.go
voor het binaire bestand met behulp van-o
flaggo build -o my_c_binding main.go
Ik hoop dat je deze tutorial leuk vond.