Pourquoi Go n'est pas une île, mais un pont
\n\nGo est un langage remarquable. Il est rapide, compilé, avec une excellente bibliothèque standard. Mais soyons honnêtes : dans le monde réel, nous écrivons rarement tout à partir de zéro dans un seul langage. Vous avez une ancienne bibliothèque C éprouvée qu'il serait dommage de réécrire. Ou un super script Python pour l'apprentissage automatique. Ou vous voulez exécuter la logique Go directement dans le navigateur.
\nEt là se pose la question : comment intégrer Go avec d'autres langages ? N'ayez crainte, Go a été spécialement conçu pour être un bon « voisin ». Dans cet article sur PythonLib, nous allons analyser les trois principales façons de faire collaborer votre programme Go avec du code étranger. Vous apprendrez comment fonctionne cgo, comment appeler des fonctions Python via des appels système et même comment compiler Go en WebAssembly.
Intégration de Go avec C via cgo : un classique
\n\nLe chemin le plus direct et le plus puissant est cgo. Ce n'est pas une bibliothèque, mais un mécanisme intégré de Go qui permet à votre code d'appeler directement des fonctions C. Comment ça marche ? Vous écrivez simplement l'import "C" et, avant lui, un commentaire avec du code C. Le compilateur Go assemble le tout.
Écrivons notre premier programme avec cgo
\n\nÉcrivons un exemple simple : appelons le printf standard du C. Créez un fichier main.go :
package main\n\n/*\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid hello_cgo(const char* name) {\n printf("Bonjour depuis C, %s!\\n", name);\n}\n*/\nimport "C"\nimport "unsafe"\n\nfunc main() {\n name := C.CString("Gopher")\n defer C.free(unsafe.Pointer(name))\n C.hello_cgo(name)\n}\n\n\nExécutez : go run main.go. Si vous avez GCC (ou MinGW sous Windows) installé, tout sera compilé. Vous verrez « Bonjour depuis C, Gopher! ». Magique !
Important : C.CString alloue de la mémoire dans le tas C, donc nous devons la libérer via C.free. Sinon, fuite mémoire. Cgo exige de la discipline.
Transmission de types complexes : les structures
\n\nSouvent, il faut travailler non pas avec des chaînes, mais avec des structures. Supposons que nous ayons une bibliothèque C pour travailler avec des matrices. Nous voulons lui passer une structure Go. Faisons-le :
\n\npackage main\n\n/*\ntypedef struct {\n int x;\n int y;\n int result;\n} Point;\n\nPoint add_points(Point a, Point b) {\n Point r;\n r.x = a.x + b.x;\n r.y = a.y + b.y;\n r.result = r.x + r.y;\n return r;\n}\n*/\nimport "C"\nimport "fmt"\n\ntype GoPoint struct {\n X, Y, Result int\n}\n\nfunc main() {\n a := C.Point{x: 10, y: 20}\n b := C.Point{x: 30, y: 40}\n r := C.add_points(a, b)\n\n goPoint := GoPoint{\n X: int(r.x),\n Y: int(r.y),\n Result: int(r.result),\n }\n fmt.Printf("Go a reçu : Point{X:%d, Y:%d, Result:%d}\\n", goPoint.X, goPoint.Y, goPoint.Result)\n}\n\n\nNotez : nous convertissons explicitement les types C en types Go. Cgo ne sait pas mapper automatiquement les structures, donc vous êtes toujours responsable de la conversion. C'est l'un des principaux compromis de l'intégration de Go avec le langage C.
\n\nQuand cgo n'est pas nécessaire
\nN'utilisez pas cgo si :
\n- \n
- Vous avez simplement besoin d'appeler une commande dans le terminal — utilisez
os/exec. \n - Vous écrivez du code multiplateforme — cgo complique la compilation. \n
- Les performances ne sont pas critiques — cgo ajoute une surcharge due au changement de contexte. \n
Intégration de Go avec Python : scriptez intelligemment
\n\nPython et Go forment une excellente paire. Go pour la vitesse et le parallélisme, Python pour la flexibilité et l'écosystème (NumPy, TensorFlow). Comment les faire collaborer ? Nous avons deux approches : la « lourde » (via cgo et l'API C de Python) et la « légère » (via les sous-processus).
\n\nMéthode 1 : Appeler Python via os/exec (simple et fiable)
\n\nLa méthode la plus sûre pour l'apprentissage est d'exécuter un script Python en tant que processus séparé