Suche…
Cgo: Erste Schritte Tutorial
Einige Beispiele, um den Arbeitsablauf bei der Verwendung von Go-C-Bindungen zu verstehen
Was
In Go können Sie mit cgo C-Programme und Funktionen aufrufen . Auf diese Weise können Sie problemlos C-Bindungen für andere Anwendungen oder Bibliotheken erstellen, die C-API bereitstellen.
Wie
Alles, was Sie tun müssen, ist, ein import "C"
am Anfang Ihres Go-Programms hinzuzufügen, unmittelbar nachdem Sie Ihr C-Programm hinzugefügt haben:
//#include <stdio.h> import "C"
Mit dem vorherigen Beispiel können Sie das stdio
Paket in Go verwenden.
Wenn Sie eine App verwenden müssen, die sich in demselben Ordner befindet, verwenden Sie dieselbe Syntax wie in C (mit "
anstelle von <>
)".
//#include "hello.c" import "C"
WICHTIG : Lassen Sie keine Newline zwischen den Anweisungen
include
undimport "C"
Andernfalls erhalten Sie diese Art von Fehlern beim Build:
# command-line-arguments could not determine kind of name for C.Hello could not determine kind of name for C.sum
Das Beispiel
In diesem Ordner finden Sie ein Beispiel für C-Bindungen. Wir haben zwei sehr einfache "Bibliotheken" namens hello.c
:
//hello.c #include <stdio.h> void Hello(){ printf("Hello world\n"); }
Das druckt einfach "Hallo Welt" in der Konsole und in sum.c
//sum.c #include <stdio.h> int sum(int a, int b) { return a + b; }
... das nimmt 2 Argumente und gibt die Summe zurück (nicht drucken).
Wir haben ein main.go
Programm, das diese beiden Dateien verwenden wird. Zuerst importieren wir sie wie zuvor erwähnt:
//main.go package main /* #include "hello.c" #include "sum.c" */ import "C"
Hallo Welt!
Jetzt können wir die C-Programme in unserer Go-App verwenden. Versuchen wir zuerst das Hello-Programm:
//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 }
Führen Sie nun das main.go-Programm mit dem go run main.go
, um den Ausdruck des C-Programms zu erhalten: "Hallo Welt!". Gut gemacht!
Summe der Beträge
Lassen Sie uns etwas komplexer machen, indem Sie eine Funktion hinzufügen, die die beiden Argumente summiert.
//sum.c #include <stdio.h> int sum(int a, int b) { return a + b; }
Und wir rufen es von unserer vorherigen Go-App an.
//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 }
Schauen Sie sich die "makeSum" -Funktion an. Es empfängt zwei int
Parameter, die zuvor mithilfe der C.int
Funktion in C int
C.int
müssen. Die Rückgabe des Anrufs gibt uns auch ein C int
und einen Fehler, falls etwas schief gelaufen ist. Wir müssen eine C-Antwort mit int()
auf ein int von Go setzen.
Versuchen Sie, unsere Go-App mit go run main.go
$ go run main.go Hello world! Sum of 5 + 4 is 9
Eine Binärdatei erzeugen
Wenn Sie einen go-Build versuchen, könnten Sie mehrere Definitionsfehler erhalten.
$ 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
Der Trick besteht darin, direkt auf die Hauptdatei zu verweisen, wenn Sie go build
:
$ go build main.go $ ./main Hello world! Sum of 5 + 4 is 9
Denken Sie daran, dass Sie der Binärdatei einen Namen geben können, indem Sie das Flag
-o
verwenden.go build -o my_c_binding main.go
Ich hoffe, dir hat dieses Tutorial gefallen.