Maison  >  Article  >  développement back-end  >  Le langage Go est-il compatible avec le langage C ?

Le langage Go est-il compatible avec le langage C ?

青灯夜游
青灯夜游original
2022-12-26 10:23:045532parcourir

Le langage Go est compatible avec le langage C ; le langage Go peut appeler le langage C et peut également appeler le langage C. Il existe une commande Cgo dans la boîte à outils du langage Go, qui est utilisée pour gérer les opérations liées à Go appelant C ; et les fonctions Go peuvent être exportées vers C, ajoutez simplement "//export funcname" devant la fonction à exporter, et vous pouvez alors utiliser la commande "go build -buildmode=c-shared -o libxxx.so" pour compiler et générer des bibliothèques dynamiques et des fichiers d'en-tête à utiliser en langage C.

Le langage Go est-il compatible avec le langage C ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, GO version 1.18, ordinateur Dell G3.

Le langage C et le golang sont compatibles. Le fichier .c que vous avez écrit en C peut être référencé par golang et utilisé directement.

La plupart des différents langages de programmation modernes de haut niveau sont construits sur le langage C et peuvent fondamentalement appeler le langage C, et dans certains cas, cela a également cette exigence et ce sens d'existence. Le langage Go prend très bien en charge cet aspect. Il peut non seulement appeler le langage C, mais aussi appeler le langage C. Cet article expliquera le contenu pertinent.

Description de base

Il existe une commande Cgo dans la boîte à outils du langage Go, qui est utilisée pour gérer les opérations liées à Go appelant C. Nous pouvons utiliser cette commande directement ou l'appeler automatiquement lors de l'exécution ou de la construction d'un programme Go.

Le traitement du langage C par Cgo lui-même repose sur la chaîne d'outils de compilation liée au langage C dans le système, vous devez donc faire attention aux paramètres, principalement aux paramètres des variables d'environnement de Go :

Le langage Go est-il compatible avec le langage C ?

Une attention particulière doit être accordée à Les exigences de Cgo Enabled peuvent être définies à l'aide de la commande go env -w CGO_ENABLED=1. Dans l'image ci-dessus, vous pouvez voir certains paramètres FLAGS lors de la compilation C. Si nécessaire, vous pouvez ajuster les paramètres en conséquence. De plus, le CC CXX ci-dessus est le réglage de la chaîne d'outils de compilation, qui peut également être ajusté en fonction des besoins. go env -w CGO_ENABLED=1 命令来设置。上图中可以看到一些C编译时的FLAGS参数,如果有需要也可以进行相应设置调整。另外上面的 CC CXX 是编译工具链的设置,也可以根据需求设置调整。

Go中调用C

Go中调用C语言最终在Go中都显示为名为 C 的伪包, 在Go中 import "C" 行之上以注释 #include ... 方式来引用C语言相关的库。 这些被引用的库中公共的变量和函数等在Go中会被挂到 C 包中以供使用。下面是个简单的演示:

Le langage Go est-il compatible avec le langage C ?

在Go中调用C只要上面这样就行了,使用起来还是很方便的。

通常来说C语言程序的项目中除了C语言代码外可能还有汇编代码;或者项目也有可能是C/C++混合编程的。这些项目都可以在Go中使用,Cgo会自动识别后缀为 .c .s .S .sx .cc .cpp .cxx 的文件,并调用对应的编译器去编译。

需要注意的是C++中的重载和类方法等C不支持的语法想要在Go中使用都需要用C语言标准函数包装一层,使用方法就和C语言中调用C++一样。【相关推荐:Go视频教程编程教学

C中调用Go

下面测试中如果有问题可以尝试 go clean 重置项目后再进行。

Go的函数可以导出给C用,只要在要导出的函数前面加上 //export funcname 就行了,然后可以使用 go build -buildmode=c-shared -o libxxx.so 命令编译生成动态库和头文件供C语言中使用:

Le langage Go est-il compatible avec le langage C ?
Le langage Go est-il compatible avec le langage C ?

另外也可以使用 go build -buildmode=c-archive -o libxxx.a 编译生成可用C语言使用的静态库。

数据类型差异

两个语言间调用其实就是数据的传递处理,需要注意的是因为两者毕竟不是同一种语言所以两者之间可以交互的数据类型是有限制的。有些时候也会有强制转换数据类型的需求,比如下面这个代码:

package rand

// #include <stdlib.h>
import "C"

func Random() int {
    return int(C.random()) // C函数返回值给Go,random的返回值是long类型
}

func Seed(i int) {
    C.srandom(C.uint(i)) // Go传值给C的函数,srandom函数接收uint类型数据
}

两者间可用的基本数值类型转换有下面一些:

C.char,       C.schar (signed char),       C.uchar (unsigned char)
C.short,       C.ushort (unsigned short)
C.int,       C.uint (unsigned int)
C.long,       C.ulong (unsigned long)
C.longlong (long long),       C.ulonglong (unsigned long long)
C.float,       C.double
C.complexfloat (complex float),       C.complexdouble (complex double)

除了上面的基础类型,指针也是可以传递的。特别的C语言中的 void* 指针相当于Go中的 unsafe.Pointer

C中的 __int128_t__uint128_t 相当于Go中的 [16]byte

🎜🎜Call C in Go🎜🎜🎜L'appel du langage C dans Go sera éventuellement affiché sous la forme d'un pseudo package nommé C dans Go, 🎜in Go#include ... au-dessus de la ligne code>import "C" pour référencer les bibliothèques liées au langage C. 🎜 Les variables et fonctions publiques de ces bibliothèques référencées seront liées au package C pour une utilisation dans Go. Voici une démonstration simple : 🎜🎜Insérer la description de l'image ici 🎜 🎜Pour appeler C dans Go, faites simplement ce qui précède, et c'est très pratique à utiliser. 🎜🎜De manière générale, les projets de programmes en langage C peuvent inclure du code assembleur en plus du code en langage C ou le projet peut également être une programmation mixte C/C++. Ces projets peuvent être utilisés dans Go, et Cgo reconnaîtra automatiquement le suffixe comme .c .s .S .sx code > <code>.cc .cpp .cxx et appelez le compilateur correspondant pour compiler. 🎜🎜Il convient de noter que la syntaxe non prise en charge par C, telle que la surcharge et les méthodes de classe en C++, doit être enveloppée dans une couche de fonctions standard du langage C si vous souhaitez l'utiliser dans Go. La méthode d'utilisation est la même que pour appeler C++. en langage C. [Recommandations associées : Tutoriel vidéo Go🎜, Enseignement de la programmation🎜]🎜🎜🎜🎜Appelez Go en C🎜🎜🎜S'il y en a le test suivant S'il y a un problème, vous pouvez essayer go clean pour réinitialiser le projet et réessayer. 🎜🎜Les fonctions Go peuvent être exportées vers C. Ajoutez simplement //export funcname devant la fonction à exporter, puis utilisez go build -buildmode=c -shared La commande -o libxxx.so compile et génère des bibliothèques dynamiques et des fichiers d'en-tête à utiliser en langage C : 🎜🎜Insérer la description de l'image ici
Insérer la description de l'image ici🎜🎜De plus, vous pouvez également utiliser go build -buildmode=c-archive -o libxxx.a pour compiler et générer une bibliothèque statique qui peut être utilisé en langage C. 🎜🎜
🎜🎜Différences de types de données🎜🎜🎜L'appel entre les deux langues est en fait le traitement de transfert de données. Il convient de noter que parce que les deux ne sont pas la même langue après tout, ils peuvent interagir les uns avec les autres. Les types de données sont restreints. Parfois, il est nécessaire de forcer la conversion de types de données, comme le code suivant : 🎜
C.f(&C.arr[0])
🎜Les conversions de types numériques de base disponibles entre les deux sont les suivantes : 🎜
package print

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s) // 这个方式会将字符串拷贝一份,返回指针,注意使用完需要释放内存
    defer C.free(unsafe.Pointer(cs)) // defer修饰的语句会在该函数退出前执行
    C.fputs(cs, (*C.FILE)(C.stdout))
}
🎜En plus des types de base ci-dessus, des pointeurs peuvent également être transmis. En particulier, le pointeur void* dans le langage C est équivalent au unsafe.Pointer dans Go. 🎜🎜__int128_t et __uint128_t en C sont équivalents à [16]byte en Go. 🎜

C中函数传输参数为数组的话直接传递数组名就行,在Go中向这类函数传递数组需要传递数组第一个元素的地址,另外需要注意的是数组中元素也必须是C语言中支持的类型:

C.f(&C.arr[0])

C中并没有string类型,使用字符串时需要进行处理:

package print

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s) // 这个方式会将字符串拷贝一份,返回指针,注意使用完需要释放内存
    defer C.free(unsafe.Pointer(cs)) // defer修饰的语句会在该函数退出前执行
    C.fputs(cs, (*C.FILE)(C.stdout))
}

另外C语言的字符串 *C.char 可以使用 C.GoString() 转换成Go中的字符串。

C中的 struct union enum 这些类型在Go使用需要加上对应的前缀,变成 struct_xxx union_xxx enum_xxx 。其中联合体在Go中将成为字节数组的形式。这些对象的成员名如果和Go的关键词一样的话,在Go中使用需要在成员名前面加下划线,比如 x._name

C中的 sizeof 在Go中需要使用 C.sizeof_T 方式使用,T是变量数据类型。

更多编程相关知识,请访问:编程视频!!

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn