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
includeen 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.govoor het binaire bestand met behulp van-oflaggo build -o my_c_binding main.go
Ik hoop dat je deze tutorial leuk vond.