Heim >Backend-Entwicklung >Golang >Erfahrungsaustausch: Wie sich Golang und C-Sprache gegenseitig nennen!

Erfahrungsaustausch: Wie sich Golang und C-Sprache gegenseitig nennen!

藏色散人
藏色散人nach vorne
2021-11-25 14:55:354358Durchsuche

Dieser Artikel wurde von der Go-SpracheTutorial-Kolumne geschrieben, um Ihnen vorzustellen, wie sich Golang und C-Sprache gegenseitig nennen. Ich hoffe, dass er Freunden in Not hilfreich sein wird!

Gegenseitige Aufrufe zwischen Go-Sprache und C-Sprache

Aus beruflichen Gründen ist es in letzter Zeit notwendig, gegenseitige Aufrufe zwischen Go-Sprache und C-Sprache zu implementieren. Da die Go-Sprache und die C-Sprache untrennbar miteinander verbunden sind, können die Aufrufe zwischen den beiden über die Sprachebene realisiert werden. Nachfolgend finden Sie eine Zusammenfassung davon.

Go-Sprache ruft C-Sprache auf

Das Folgende ist ein kurzes Beispiel:

package main

// #include <stdio.h>
// #include <stdlib.h>
/*
void print(char *str) {
    printf("%s\n", str);
}
*/
import "C"

import "unsafe"

func main() {
    s := "Hello Cgo"
    cs := C.CString(s)
    C.print(cs)
    C.free(unsafe.pointer(cs))
}

Im Vergleich zum „normalen“ Go-Code weist der obige Code mehrere „besondere“ Dinge auf:

  • erscheint in den Kommentaren am Anfang Das Include Wort in der C-Sprach-Header-Datei

  • definiert die C-Sprachfunktion print im Kommentar

  • importiert ein „Paket“ mit dem Namen C

  • ruft die oben in der Hauptfunktion definierte C-Sprachfunktion print auf

Erstens muss der C-Sprachcode in der Go-Quelldatei mit Kommentaren umschlossen werden, genau wie die obige Include-Header-Datei und die Druckfunktionsdefinition. Zweitens ist die Import-Anweisung „C“ erforderlich, die mit The zusammenhängt Die oben genannten C-Codes dürfen nicht durch Leerzeilen getrennt werden und müssen eng miteinander verbunden sein. Das „C“ ist hier kein Paketname, sondern ein Konzept ähnlich einem Namespace, oder es kann als Pseudopaket verstanden werden. Alle Syntaxelemente der C-Sprache befinden sich schließlich unter diesem Pseudopaket c-Syntaxelemente, sie müssen im obigen Code Pseudopaketpräfixe wie C.uint und C.print, C.free usw. hinzufügen.

Für eine detailliertere Verwendung des Aufrufs der C-Sprache in Go lesen Sie bitte die Interoperabilität zwischen Go und C-Sprache. In diesem Artikel wird nicht einzeln darauf eingegangen.

Im obigen Beispiel ist die C-Sprache in den Go-Code eingebettet. Wenn der Code größer und komplexer ist, ist dies offensichtlich sehr unprofessionell. Kann der C-Sprachcode also vom Go-Code getrennt und separat definiert werden? Die Antwort lautet: Ja, dies kann über gemeinsam genutzte Bibliotheken erreicht werden.

cgo stellt die Anweisung #cgo bereit, um anzugeben, mit welchen gemeinsam genutzten Bibliotheken der Go-Quellcode nach der Kompilierung verknüpft wird. Das Beispiel sieht wie folgt aus: #cgo指示符可以指定go源码在编译后与哪些共享库进行链接。例子如下:

// hello.go
package main

// #cgo LDFLAGS: -L ./ -lhello
// #include <stdio.h>
// #include <stdlib.h>
// #include "hello.h"
import "C"

func main() {
    C.hello()
}

// hello.c
#include "hello.h"

void hello()
{
    printf("hello, go\n");
}

// hello.h
extern void hello();

其中在hello.go中,#cgo指示符后面添加LDFLAGS: -L ./ -lhello,作用是在go代码编译时,指定在当前目录查找so库并进行链接。

因此,只需要把hello.c编译成动态库,再编译go代码,即可在运行go代码的时候调用共享库中的c语言函数。指令如下:

  • gcc -fPIC -o libhello.so hello.c

  • go build -o hello

  • ./hello

c语言调用go语言

与在go中调用c源码相比,在c中使用go函数的场合较少。因为一般来说,采用高级语言作为粘合剂调用低级语言能充分发挥各自的特点,而用低级语言调用高级语言反而有可能降低低级语言的性能优势,在go中,可以使用”export + 函数名“来导出go函数为c代码所用,看一个简单的例子:

// hello.go
package main

import "C"

import "fmt"

// export Go2C
func Go2C() {
    fmt.Println("hello, C")
}

可通过go build的编译选项,将go代码编译成共享库以供c代码调用。注意,编译so库时必须存在main及main函数(即使main函数为空)。编译指令如下:go build -v -x -buildmode=c-shared -o libhello.so hello.go

编译成功后,只需在c代码中引入新生成的头文件及编译时链接动态库即可实现go函数的调用。代码如下:

// hello.c
#include <stdio.h>
#include "libhello.h"

int main()
{
    Go2C();
    return 0;
}

通过gcc -o hello -L. -lhello,即可编译成可执行程序。注意,运行前必须确定共享库运行时查找路径中存在需要链接的共享库,可通过将so库路径放到/usr/lib或者修改环境变量LD_LIBRARY_PATH。

小结

go语言可以通过内嵌c代码的形式调用c语言,也可以通过调用共享库函数的方式实现;至于c语言调用go函数,则可以通过go buildrrreee

Fügen Sie in hello.go LDFLAGS: -L ./ -lhello nach dem Indikator #cgo hinzu, der beim Kompilieren von Go-Code verwendet wird . Gibt an, nach der so-Bibliothek im aktuellen Verzeichnis zu suchen und sie zu verknüpfen.
🎜 Daher müssen Sie nur hello.c in eine dynamische Bibliothek kompilieren und dann den Go-Code kompilieren, und Sie können die C-Sprachfunktion in der gemeinsam genutzten Bibliothek aufrufen, wenn Sie den Go-Code ausführen. Die Anweisungen lauten wie folgt: 🎜🎜🎜🎜gcc -fPIC -o libhello.so hello.c🎜🎜🎜🎜go build -o hello🎜🎜🎜🎜./ hallo🎜🎜🎜🎜C-Sprachaufrufe go-Sprache🎜🎜Im Vergleich zum Aufrufen von C-Quellcode in Go gibt es weniger Gelegenheiten, Go-Funktionen in C zu verwenden. Denn im Allgemeinen kann die Verwendung von Sprachen auf hoher Ebene als Klebstoff zum Aufrufen von Sprachen auf niedriger Ebene ihre jeweiligen Eigenschaften voll zur Geltung bringen, während die Verwendung von Sprachen auf niedriger Ebene zum Aufrufen von Sprachen auf hoher Ebene dies verringern kann Leistungsvorteile von Low-Level-Sprachen. In Go können Sie „Export + Funktionsname“ verwenden. „Um Go-Funktionen zur Verwendung durch C-Code zu exportieren, sehen Sie sich ein einfaches Beispiel an: 🎜rrreee🎜 Sie können die Kompilierungsoption von verwenden go build, um Go-Code in einer gemeinsam genutzten Bibliothek zu kompilieren, damit C-Code aufgerufen werden kann. Beachten Sie, dass beim Kompilieren der so-Bibliothek main und main-Funktionen vorhanden sein müssen (auch wenn die main-Funktion leer ist). Die Kompilierungsanweisungen lauten wie folgt: go build -v -x -buildmode=c-shared -o libhello.so hello.go. 🎜🎜Nach erfolgreicher Kompilierung müssen Sie lediglich die neu generierte Header-Datei in den C-Code einführen und die dynamische Bibliothek während der Kompilierung verknüpfen, um den Aufruf der Go-Funktion zu realisieren. Der Code lautet wie folgt: 🎜rrreee🎜Verwenden Sie gcc -o hello -L -lhello, um ihn in ein ausführbares Programm zu kompilieren. Beachten Sie, dass Sie vor der Ausführung sicherstellen müssen, dass die gemeinsam genutzte Bibliothek, die verknüpft werden muss, im Laufzeitsuchpfad der gemeinsam genutzten Bibliothek vorhanden ist. Sie können den Bibliothekspfad in /usr/lib einfügen oder die Umgebungsvariable LD_LIBRARY_PATH ändern. 🎜🎜Zusammenfassung🎜🎜go-Sprache kann C-Sprache aufrufen, indem C-Code eingebettet wird, oder indem gemeinsam genutzte Bibliotheksfunktionen aufgerufen werden; für den Aufruf von Go-Funktionen in C-Sprache können Sie go build verwenden. Go-Code wird in einen gemeinsam genutzten Code kompiliert Bibliothek zur Verwendung durch C-Code. Beachten Sie, dass es sich bei den gemeinsam genutzten Bibliotheken in diesem Artikel ausschließlich um dynamische gemeinsam genutzte Bibliotheken handelt. Sie wurden nicht getestet. Interessierte können sie implementieren. 🎜🎜

Das obige ist der detaillierte Inhalt vonErfahrungsaustausch: Wie sich Golang und C-Sprache gegenseitig nennen!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen