En la charla tecnológica, SWIG se mencionó brevemente, algo así como "... hasta que terminemos el trago ..."
StackedCrooked
1
@Matt: Probablemente quiera usar una biblioteca C ++ existente sin tener que portarla a C o Go. Yo quería lo mismo.
Graeme Perrow
No puedo pensar en una sola biblioteca decente disponible para C ++ y no para C. Me encantaría saber lo que tienes en mente.
Matt Joiner
13
@Matt: Un ejemplo es la biblioteca Boost, y hay miles de otras bibliotecas C ++ útiles. Pero tal vez solo estoy alimentando a un troll aquí ...
Frank
@Matt: en mi caso, quería crear una interfaz Go para nuestra biblioteca cliente existente, pero la biblioteca es principalmente C ++. Portarlo a C o Go simplemente no es una opción.
Graeme Perrow
Respuestas:
154
Actualización: logré vincular una pequeña clase de prueba C ++ con Go
Si ajusta su código C ++ con una interfaz C, debería poder llamar a su biblioteca con cgo (consulte el ejemplo de gmp in $GOROOT/misc/cgo/gmp).
No estoy seguro de si la idea de una clase en C ++ es realmente expresable en Go, ya que no tiene herencia.
Tenga cuidado con esto, no tengo idea de lo que podría pasarle a la memoria si la envía entre los dos idiomas.
Scott Wales
11
Debo decir que este ejemplo me recuerda por qué quiero escribir Go puro. Mira cuánto más grande y feo es el lado de C ++. Ick
Jeff Allen
@ScottWales, ¿hay alguna posibilidad de que haya puesto esto en un repositorio en Github o algo así? Me encantaría ver un ejemplo de trabajo
netpoetica
77
@Arne: No rechazas una respuesta porque no es la mejor. Vota una respuesta en contra porque no es útil. Mientras funcione, esta respuesta sigue siendo útil, incluso si hay mejores soluciones.
Graeme Perrow
Buenas noticias, Go compilará cpp ahora para que el archivo MAKE ya no sea necesario. Los envoltorios inseguros de puntero no me funcionaron. Una ligera modificación compilada para mí: play.golang.org/p/hKuKV51cRpgo test debería funcionar sin el archivo MAKE
Drew
47
Parece que actualmente SWIG es la mejor solución para esto:
Es compatible con la herencia e incluso permite la subclase de la clase C ++ con Go struct, de modo que cuando se invocan métodos anulados en el código C ++, se activa el código Go.
¿Los programas Go se vinculan con los programas C / C ++?
Hay dos implementaciones del compilador Go, gc (el programa 6g y amigos) y gccgo. Gc usa una convención de llamada y un enlazador diferentes y, por lo tanto, solo se puede vincular con programas en C que usan la misma convención. Existe un compilador de C pero no un compilador de C ++. Gccgo es un front-end de GCC que, con cuidado, puede vincularse con programas C o C ++ compilados con GCC.
El programa cgo proporciona el mecanismo para una "interfaz de función externa" para permitir la llamada segura de las bibliotecas C desde el código Go. SWIG extiende esta capacidad a las bibliotecas de C ++.
Puedo ejecutar el programa de ejemplo de la siguiente manera:
$ 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)
Importante
Los comentarios anteriores import "C"en el goprograma NO SON OPCIONALES . Debe colocarlos exactamente como se muestra para que cgosepa qué encabezado y biblioteca cargar, en este caso:
Parece que es una de las primeras preguntas sobre Golang. Y al mismo tiempo responde que nunca se actualizará. Durante estos tres o cuatro años, se han publicado demasiadas bibliotecas y publicaciones de blog nuevas. Debajo están los pocos enlaces que me parecieron útiles.
Se habla de interoperabilidad entre C y Go cuando se usa el compilador gcc Go, gccgo. Sin embargo, existen limitaciones tanto para la interoperabilidad como para el conjunto de características implementadas de Go cuando se usa gccgo (por ejemplo, goroutines limitados, no recolección de basura).
1. Cree un lenguaje sin facilidades para la gestión manual de la memoria. 2. ¿Elimine la recolección de basura? ¿Soy el único que se rasca la cabeza ante esto?
György Andrasek
2
Estás caminando en territorio desconocido aquí. Aquí está el ejemplo de Go para llamar al código C, tal vez pueda hacer algo así después de leer sobre la convención de nombres y llamadas de C ++ , y muchas pruebas y errores.
Si todavía tienes ganas de probarlo, buena suerte.
El problema aquí es que una implementación compatible no necesita colocar sus clases en un archivo de compilación .cpp. Si el compilador puede optimizar la existencia de una clase, siempre que el programa se comporte de la misma manera sin ella, entonces puede omitirse del ejecutable de salida.
C tiene una interfaz binaria estandarizada. Por lo tanto, podrá saber que sus funciones se exportan. Pero C ++ no tiene ese estándar detrás.
Es curioso cuántos problemas más amplios ha desenterrado este anuncio. Dan Lyke tuvo una discusión muy entretenida y reflexiva en su sitio web, Flutterby, sobre el desarrollo de estándares entre procesos como una forma de iniciar nuevos lenguajes (y otras ramificaciones, pero esa es la que está relacionada aquí).
En esencia 'Si la importación de "C" está precedida inmediatamente por un comentario, ese comentario, llamado preámbulo, se usa como encabezado al compilar las partes C del paquete. Por ejemplo: '
fuente: https://golang.org/cmd/cgo/
Respuestas:
Actualización: logré vincular una pequeña clase de prueba C ++ con Go
Si ajusta su código C ++ con una interfaz C, debería poder llamar a su biblioteca con cgo (consulte el ejemplo de gmp in
$GOROOT/misc/cgo/gmp
).No estoy seguro de si la idea de una clase en C ++ es realmente expresable en Go, ya que no tiene herencia.
Aquí hay un ejemplo:
Tengo una clase de C ++ definida como:
que quiero usar en Go. Usaré la interfaz C
(Utilizo una
void*
estructura en lugar de una C para que el compilador conozca el tamaño de Foo)La implementación es:
Con todo eso hecho, el archivo Go es:
El makefile que solía compilar era:
Intenta probarlo con:
Deberá instalar la biblioteca compartida con make install y luego ejecutar make test. La salida esperada es:
fuente
go test
debería funcionar sin el archivo MAKEParece que actualmente SWIG es la mejor solución para esto:
http://www.swig.org/Doc2.0/Go.html
Es compatible con la herencia e incluso permite la subclase de la clase C ++ con Go struct, de modo que cuando se invocan métodos anulados en el código C ++, se activa el código Go.
La sección sobre C ++ en Preguntas frecuentes sobre Go se actualiza y ahora menciona SWIG y ya no dice " porque Go es basura recolectada, no será prudente hacerlo, al menos ingenuamente ".
fuente
Todavía no puedes ver lo que leí en las preguntas frecuentes :
fuente
A partir de go1.2 +, cgo incorpora y compila automáticamente el código C ++:
http://golang.org/doc/go1.2#cgo_and_cpp
fuente
He creado el siguiente ejemplo basado en la respuesta de Scott Wales . Lo probé en la
go
versión de macOS High Sierra 10.13.3go1.10 darwin/amd64
.(1) Código para
library.hpp
la API de C ++ que pretendemos llamar.(2) Código para
library.cpp
la implementación de C ++.(3) Código para
library-bridge.h
el puente necesario para exponer unaC
API implementadaC++
para quego
pueda usarla.(4) Código para
library-bridge.cpp
la implementación del puente.(5) Finalmente,
library.go
el programa go llama a la API de C ++.Usando el siguiente Makefile
Puedo ejecutar el programa de ejemplo de la siguiente manera:
Importante
Los comentarios anteriores
import "C"
en elgo
programa NO SON OPCIONALES . Debe colocarlos exactamente como se muestra para quecgo
sepa qué encabezado y biblioteca cargar, en este caso:Enlace al repositorio de GitHub con el ejemplo completo .
fuente
Parece que es una de las primeras preguntas sobre Golang. Y al mismo tiempo responde que nunca se actualizará. Durante estos tres o cuatro años, se han publicado demasiadas bibliotecas y publicaciones de blog nuevas. Debajo están los pocos enlaces que me parecieron útiles.
SWIG and Go
Llamar a código C ++ desde ir con SWIG
Al comparar lenguajes, C ++ y Go
GoForCPPProgrammers
fuente
Se habla de interoperabilidad entre C y Go cuando se usa el compilador gcc Go, gccgo. Sin embargo, existen limitaciones tanto para la interoperabilidad como para el conjunto de características implementadas de Go cuando se usa gccgo (por ejemplo, goroutines limitados, no recolección de basura).
fuente
Estás caminando en territorio desconocido aquí. Aquí está el ejemplo de Go para llamar al código C, tal vez pueda hacer algo así después de leer sobre la convención de nombres y llamadas de C ++ , y muchas pruebas y errores.
Si todavía tienes ganas de probarlo, buena suerte.
fuente
El problema aquí es que una implementación compatible no necesita colocar sus clases en un archivo de compilación .cpp. Si el compilador puede optimizar la existencia de una clase, siempre que el programa se comporte de la misma manera sin ella, entonces puede omitirse del ejecutable de salida.
C tiene una interfaz binaria estandarizada. Por lo tanto, podrá saber que sus funciones se exportan. Pero C ++ no tiene ese estándar detrás.
fuente
Es posible que deba agregar
-lc++
aLDFlags
Golang / CGo para reconocer la necesidad de la biblioteca estándar.fuente
Es curioso cuántos problemas más amplios ha desenterrado este anuncio. Dan Lyke tuvo una discusión muy entretenida y reflexiva en su sitio web, Flutterby, sobre el desarrollo de estándares entre procesos como una forma de iniciar nuevos lenguajes (y otras ramificaciones, pero esa es la que está relacionada aquí).
fuente
Esto se puede lograr usando el comando cgo.
En esencia 'Si la importación de "C" está precedida inmediatamente por un comentario, ese comentario, llamado preámbulo, se usa como encabezado al compilar las partes C del paquete. Por ejemplo: '
fuente: https://golang.org/cmd/cgo/
fuente