Maison  >  Article  >  développement back-end  >  Partage d'expérience : comment le golang et le langage c s'appellent !

Partage d'expérience : comment le golang et le langage c s'appellent !

藏色散人
藏色散人avant
2021-11-25 14:55:354317parcourir

Cet article est écrit par la rubrique tutoriel go language pour vous présenter comment le golang et le langage c s'appellent. J'espère qu'il sera utile aux amis dans le besoin !

Appels mutuels entre le langage go et le langage c

Récemment, pour des raisons professionnelles, il est nécessaire de mettre en œuvre des appels mutuels entre le langage go et le langage c. Le langage Go et le langage C étant inextricablement liés, les appels entre les deux peuvent se réaliser à travers le niveau du langage. Vous en trouverez ci-dessous un résumé.

le langage go appelle le langage c

Ce qui suit est un court exemple :

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))
}

Par rapport au code go "normal", le code ci-dessus a plusieurs choses "spéciales" :

  • apparaît dans les commentaires au début L'inclusion word dans le fichier d'en-tête du langage c

  • définit la fonction du langage c print dans le commentaire

  • importe un "package" nommé C

  • appelle le langage c défini ci-dessus dans la fonction principale Function print

Tout d'abord, le code du langage C dans le fichier source go doit être enveloppé de commentaires, tout comme le fichier d'en-tête d'inclusion et la définition de la fonction d'impression ci-dessus. Deuxièmement, l'instruction d'importation "C" est nécessaire et elle est liée à The ; Les codes C ci-dessus ne peuvent pas être séparés par des lignes vides et doivent être étroitement liés. Le "C" ici n'est pas un nom de package, mais un concept similaire à un espace de noms, ou il peut être compris comme un pseudo-paquet. Tous les éléments de syntaxe du langage C se trouvent finalement sous ce pseudo-paquet, lors de l'accès à la syntaxe C ; éléments, ils doivent être devant lui. Ajoutez des préfixes de pseudo-package, tels que C.uint et C.print, C.free, etc. dans le code ci-dessus.

Pour une utilisation plus détaillée de l'appel du langage C dans Go, veuillez vous référer à l'interopérabilité entre Go et le langage C. Cet article n'entrera pas dans les détails un par un.

Dans l'exemple ci-dessus, le langage C est intégré dans le code go. Si le code est plus volumineux et plus complexe, ce n'est évidemment pas du tout professionnel. Alors, le code du langage C peut-il être séparé du code Go et défini séparément ? La réponse est oui, cela peut être réalisé grâce à des bibliothèques partagées.

cgo fournit la directive #cgo pour spécifier à quelles bibliothèques partagées le code source go sera lié après la compilation. L'exemple est le suivant : #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

Dans hello.go, ajoutez LDFLAGS: -L ./ -lhello après l'indicateur #cgo, qui est utilisé lors de la compilation du code go . Spécifie qu'il faut rechercher la bibliothèque so dans le répertoire actuel et la lier.
🎜 Par conséquent, il vous suffit de compiler hello.c dans une bibliothèque dynamique, puis de compiler le code go, et vous pouvez appeler la fonction du langage c dans la bibliothèque partagée lors de l'exécution du code go. Les instructions sont les suivantes : 🎜🎜🎜🎜gcc -fPIC -o libhello.so bonjour.c🎜🎜🎜🎜go build -o bonjour🎜🎜🎜🎜./ bonjour🎜🎜🎜🎜le langage c appelle le langage go🎜🎜Par rapport à l'appel du code source c en go, il y a moins d'occasions d'utiliser les fonctions go en c. Parce que d'une manière générale, l'utilisation de langages de haut niveau comme colle pour appeler des langages de bas niveau peut faire jouer pleinement leurs caractéristiques respectives, tandis que l'utilisation de langages de bas niveau pour appeler des langages de haut niveau peut réduire la avantages en termes de performances des langages de bas niveau. Dans go, vous pouvez utiliser "export + nom de la fonction" "Pour exporter les fonctions go à utiliser par le code C, regardez un exemple simple : 🎜rrreee🎜 Vous pouvez utiliser l'option de compilation de . go build pour compiler le code go dans une bibliothèque partagée pour que le code c puisse l'appeler. Notez que les fonctions main et main doivent exister lors de la compilation de la bibliothèque so (même si la fonction main est vide). Les instructions de compilation sont les suivantes : go build -v -x -buildmode=c-shared -o libhello.so hello.go. 🎜🎜Après une compilation réussie, il vous suffit d'introduire le fichier d'en-tête nouvellement généré dans le code c et de lier la bibliothèque dynamique lors de la compilation pour réaliser l'appel de la fonction go. Le code est le suivant : 🎜rrreee🎜Utilisez gcc -o hello -L -lhello pour le compiler en un programme exécutable. Notez qu'avant d'exécuter, vous devez vous assurer qu'il existe une bibliothèque partagée qui doit être liée dans le chemin de recherche d'exécution de la bibliothèque partagée. Vous pouvez mettre le chemin de la bibliothèque donc dans /usr/lib ou modifier la variable d'environnement LD_LIBRARY_PATH. 🎜🎜Résumé🎜🎜Le langage Go peut appeler le langage C en incorporant du code C ou en appelant des fonctions de bibliothèque partagée ; comme pour le langage C appelant la fonction Go, vous pouvez utiliser go build pour que le code Go soit compilé dans un bibliothèque partagée à utiliser par le code C. Notez que les bibliothèques partagées dans cet article sont toutes des bibliothèques partagées dynamiques. Quant aux bibliothèques partagées statiques, elles n'ont pas été testées. Ceux qui sont intéressés peuvent les implémenter. 🎜🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer