Dans la discussion technique, SWIG a été très brièvement mentionné, quelque chose comme "... jusqu'à ce que nous ayons terminé la gorgée ..."
StackedCrooked
1
@Matt: Il souhaite probablement utiliser une bibliothèque C ++ existante sans avoir à la porter vers C ou Go. Je voulais la même chose.
Graeme Perrow
Je ne peux pas penser à une seule bibliothèque décente disponible pour C ++ et non pour C. J'adorerais savoir ce que vous avez en tête.
Matt Joiner
13
@Matt: Un exemple est la bibliothèque Boost, et il existe des milliers d'autres bibliothèques C ++ utiles. Mais peut-être que je nourris juste un troll ici ...
Frank
@Matt: dans mon cas, je voulais faire une interface Go à notre bibliothèque client existante mais la bibliothèque est principalement C ++. Le porter vers C ou Go n'est tout simplement pas une option.
Graeme Perrow
Réponses:
154
Mise à jour: j'ai réussi à lier une petite classe de test C ++ avec Go
Si vous enveloppez votre code C ++ avec une interface C, vous devriez pouvoir appeler votre bibliothèque avec cgo (voir l'exemple de gmp dans $GOROOT/misc/cgo/gmp).
Je ne suis pas sûr que l'idée d'une classe en C ++ soit vraiment exprimable dans Go, car elle n'a pas d'héritage.
Soyez prudent, je n'ai aucune idée de ce qui pourrait arriver à la mémoire si vous l'envoyez entre les deux langues.
Scott Wales
11
Je dois dire que cet exemple me rappelle pourquoi je veux écrire du Go pur. Regardez à quel point le côté C ++ est plus grand et plus laid. Ick.
Jeff Allen
@ScottWales, une chance que vous ayez mis cela dans un dépôt sur Github ou quoi que ce soit? J'aimerais voir un exemple fonctionnel
netpoetica
7
@Arne: Vous ne rejetez pas une réponse parce que ce n'est pas la meilleure. Vous votez contre une réponse parce qu'elle n'est pas utile. Tant que cela fonctionne, cette réponse est toujours utile même s'il existe de meilleures solutions.
Graeme Perrow
Bonne nouvelle, Go va compiler cpp maintenant donc le makefile n'est plus nécessaire. Les wrappers unsafe.Pointer ne fonctionnaient pas pour moi. Une légère modification compilée pour moi: play.golang.org/p/hKuKV51cRpgo test devrait fonctionner sans le makefile
Drew le
47
Semble que SWIG est actuellement la meilleure solution pour cela:
Il prend en charge l'héritage et permet même de sous-classer la classe C ++ avec la structure Go.Ainsi, lorsque des méthodes surchargées sont appelées dans du code C ++, le code Go est déclenché.
La section sur le C ++ dans la FAQ de Go est mise à jour et mentionne maintenant SWIG et ne dit plus « parce que Go est ramassé, il ne sera pas sage de le faire, du moins naïvement ».
J'aurais aimé qu'il y ait un moyen d'augmenter cela. Les autres réponses sont dépassées. Plus SWIG a versionné swig.org/Doc3.0/Go.html
dragonx
34
Vous ne pouvez pas encore tout à fait d'après ce que j'ai lu dans la FAQ :
Les programmes Go sont-ils liés aux programmes C / C ++?
Il existe deux implémentations du compilateur Go, gc (le programme 6g et ses amis) et gccgo. Gc utilise une convention d'appel et un éditeur de liens différents et ne peut donc être lié qu'à des programmes C utilisant la même convention. Il existe un tel compilateur C mais pas de compilateur C ++. Gccgo est un frontal GCC qui peut, avec précaution, être lié à des programmes C ou C ++ compilés par GCC.
Le programme cgo fournit le mécanisme d'une «interface de fonction étrangère» pour permettre un appel sécurisé des bibliothèques C à partir du code Go. SWIG étend cette capacité aux bibliothèques C ++.
J'ai créé l'exemple suivant basé sur la réponse de Scott Wales . Je l'ai testé dans la goversion exécutable de macOS High Sierra 10.13.3 go1.10 darwin/amd64.
(1) Code pour library.hppl'API C ++ que nous souhaitons appeler.
#pragma once
classFoo{public:Foo(intvalue);~Foo();intvalue()const;private:int m_value;};
Je peux exécuter l'exemple de programme comme suit:
$ make
clang++-o liblibrary.so library.cpp library-bridge.cpp \
-std=c++17-O3 -Wall-Wextra-fPIC -shared
$ go run library.go
[c++ bridge] LIB_NewFoo(42)[c++]Foo::Foo(42)[c++ bridge] LIB_NewFoo(42) will return pointer 0x42002e0[c++ bridge] LIB_FooValue(0x42002e0)[c++]Foo::value()is42[go]42[c++ bridge] LIB_DestroyFoo(0x42002e0)[c++]Foo::~Foo(42)
Important
Les commentaires ci-dessus import "C"dans le goprogramme ne sont PAS OPTIONNELS . Vous devez les mettre exactement comme indiqué pour cgosavoir quel en-tête et bibliothèque charger, dans ce cas:
On dirait que c'est l'une des premières questions posées sur Golang. Et en même temps, les réponses ne sont jamais mises à jour. Au cours de ces trois à quatre ans, trop de nouvelles bibliothèques et articles de blog ont été publiés. Voici les quelques liens que j'ai jugés utiles.
On parle d' interopérabilité entre C et Go lors de l'utilisation du compilateur gcc Go, gccgo. Il y a cependant des limitations à la fois à l'interopérabilité et à l'ensemble des fonctionnalités implémentées de Go lors de l'utilisation de gccgo (par exemple, goroutines limitées, pas de garbage collection).
1. Créer un langage sans possibilité de gestion manuelle de la mémoire, 2. Supprimer le ramasse-miettes? Suis-je le seul à me gratter la tête?
György Andrasek
2
Vous marchez sur un territoire inconnu ici. Voici l'exemple Go pour appeler du code C, peut-être que vous pouvez faire quelque chose comme ça après avoir lu les conventions de dénomination et d'appel C ++ , ainsi que de nombreux essais et erreurs.
Si vous avez encore envie de l'essayer, bonne chance.
Le problème ici est qu'une implémentation conforme n'a pas besoin de placer vos classes dans un fichier de compilation .cpp. Si le compilateur peut optimiser l'existence d'une classe, tant que le programme se comporte de la même manière sans elle, alors il peut être omis de l'exécutable de sortie.
C a une interface binaire normalisée. Vous pourrez ainsi savoir que vos fonctions sont exportées. Mais C ++ n'a pas une telle norme derrière lui.
C'est drôle le nombre de problèmes plus larges que cette annonce a soulevés. Dan Lyke a eu une discussion très divertissante et réfléchie sur son site Web, Flutterby, sur le développement des normes interprocessus comme un moyen d'amorcer de nouveaux langages (et d'autres ramifications, mais c'est celui qui est pertinent ici).
Ceci peut être réalisé en utilisant la commande cgo.
En substance 'Si l'importation de "C" est immédiatement précédée d'un commentaire, ce commentaire, appelé préambule, est utilisé comme en-tête lors de la compilation des parties C du package. Par exemple: '
source: https://golang.org/cmd/cgo/
Réponses:
Mise à jour: j'ai réussi à lier une petite classe de test C ++ avec Go
Si vous enveloppez votre code C ++ avec une interface C, vous devriez pouvoir appeler votre bibliothèque avec cgo (voir l'exemple de gmp dans
$GOROOT/misc/cgo/gmp
).Je ne suis pas sûr que l'idée d'une classe en C ++ soit vraiment exprimable dans Go, car elle n'a pas d'héritage.
Voici un exemple:
J'ai une classe C ++ définie comme:
que je souhaite utiliser dans Go. J'utiliserai l'interface C
(J'utilise a
void*
au lieu d'une structure C pour que le compilateur connaisse la taille de Foo)La mise en œuvre est:
avec tout cela fait, le fichier Go est:
Le makefile que j'ai utilisé pour compiler ceci était:
Essayez de le tester avec:
Vous devrez installer la bibliothèque partagée avec make install, puis exécuter make test. Le résultat attendu est:
la source
go test
devrait fonctionner sans le makefileSemble que SWIG est actuellement la meilleure solution pour cela:
http://www.swig.org/Doc2.0/Go.html
Il prend en charge l'héritage et permet même de sous-classer la classe C ++ avec la structure Go.Ainsi, lorsque des méthodes surchargées sont appelées dans du code C ++, le code Go est déclenché.
La section sur le C ++ dans la FAQ de Go est mise à jour et mentionne maintenant SWIG et ne dit plus « parce que Go est ramassé, il ne sera pas sage de le faire, du moins naïvement ».
la source
Vous ne pouvez pas encore tout à fait d'après ce que j'ai lu dans la FAQ :
la source
Depuis go1.2 +, cgo intègre et compile automatiquement le code C ++:
http://golang.org/doc/go1.2#cgo_and_cpp
la source
J'ai créé l'exemple suivant basé sur la réponse de Scott Wales . Je l'ai testé dans la
go
version exécutable de macOS High Sierra 10.13.3go1.10 darwin/amd64
.(1) Code pour
library.hpp
l'API C ++ que nous souhaitons appeler.(2) Code pour
library.cpp
, l'implémentation C ++.(3) Code pour
library-bridge.h
le pont nécessaire pour exposer uneC
API implémentée dansC++
afin dego
pouvoir l'utiliser.(4) Code pour
library-bridge.cpp
la mise en œuvre du pont.(5) Enfin,
library.go
le programme go appelant l'API C ++.Utilisation du Makefile suivant
Je peux exécuter l'exemple de programme comme suit:
Important
Les commentaires ci-dessus
import "C"
dans lego
programme ne sont PAS OPTIONNELS . Vous devez les mettre exactement comme indiqué pourcgo
savoir quel en-tête et bibliothèque charger, dans ce cas:Lien vers le dépôt GitHub avec l'exemple complet .
la source
On dirait que c'est l'une des premières questions posées sur Golang. Et en même temps, les réponses ne sont jamais mises à jour. Au cours de ces trois à quatre ans, trop de nouvelles bibliothèques et articles de blog ont été publiés. Voici les quelques liens que j'ai jugés utiles.
SWIG et Go
Appel de code C ++ depuis Go avec SWIG
Sur la comparaison des langages, C ++ et Go
Programmeurs GoForCPP
la source
On parle d' interopérabilité entre C et Go lors de l'utilisation du compilateur gcc Go, gccgo. Il y a cependant des limitations à la fois à l'interopérabilité et à l'ensemble des fonctionnalités implémentées de Go lors de l'utilisation de gccgo (par exemple, goroutines limitées, pas de garbage collection).
la source
Vous marchez sur un territoire inconnu ici. Voici l'exemple Go pour appeler du code C, peut-être que vous pouvez faire quelque chose comme ça après avoir lu les conventions de dénomination et d'appel C ++ , ainsi que de nombreux essais et erreurs.
Si vous avez encore envie de l'essayer, bonne chance.
la source
Le problème ici est qu'une implémentation conforme n'a pas besoin de placer vos classes dans un fichier de compilation .cpp. Si le compilateur peut optimiser l'existence d'une classe, tant que le programme se comporte de la même manière sans elle, alors il peut être omis de l'exécutable de sortie.
C a une interface binaire normalisée. Vous pourrez ainsi savoir que vos fonctions sont exportées. Mais C ++ n'a pas une telle norme derrière lui.
la source
Vous devrez peut-être ajouter
-lc++
auLDFlags
for Golang / CGo pour reconnaître le besoin de la bibliothèque standard.la source
C'est drôle le nombre de problèmes plus larges que cette annonce a soulevés. Dan Lyke a eu une discussion très divertissante et réfléchie sur son site Web, Flutterby, sur le développement des normes interprocessus comme un moyen d'amorcer de nouveaux langages (et d'autres ramifications, mais c'est celui qui est pertinent ici).
la source
Ceci peut être réalisé en utilisant la commande cgo.
En substance 'Si l'importation de "C" est immédiatement précédée d'un commentaire, ce commentaire, appelé préambule, est utilisé comme en-tête lors de la compilation des parties C du package. Par exemple: '
source: https://golang.org/cmd/cgo/
la source