W rozmowie technicznej SWIG był bardzo krótko wspomniany, coś w stylu „.. dopóki nie skończymy wypijać ..”
StackedCrooked
1
@Matt: Prawdopodobnie chce użyć istniejącej biblioteki C ++ bez konieczności przenoszenia jej do C lub Go. Chciałem tego samego.
Graeme Perrow
Nie przychodzi mi do głowy żadna przyzwoita biblioteka dostępna dla C ++, a nie dla C. Chciałbym wiedzieć, o czym myślisz.
Matt Joiner
13
@Matt: Jednym z przykładów jest biblioteka Boost, a istnieją tysiące innych przydatnych bibliotek C ++. Ale może po prostu karmię tutaj trolla ...
Frank,
@Matt: w moim przypadku chciałem stworzyć interfejs Go do naszej istniejącej biblioteki klienta, ale biblioteka to głównie C ++. Przeniesienie go do C lub Go po prostu nie wchodzi w grę.
Graeme Perrow
Odpowiedzi:
154
Aktualizacja: Udało mi się połączyć małą testową klasę C ++ z Go
Jeśli otoczysz kod C ++ interfejsem C, powinieneś móc wywołać swoją bibliotekę za pomocą cgo (zobacz przykład gmp w $GOROOT/misc/cgo/gmp).
Nie jestem pewien, czy idea klasy w C ++ jest naprawdę wyrażalna w Go, ponieważ nie ma dziedziczenia.
Uważaj na to, nie mam pojęcia, co może się stać z pamięcią, jeśli prześlesz ją między dwoma językami.
Scott Wales
11
Muszę powiedzieć, że ten przykład przypomina mi, dlaczego chcę pisać w czystym Go. Zobacz, o ile większa i brzydsza jest strona C ++. Ick.
Jeff Allen,
@ScottWales jest jakaś szansa, że umieściłeś to w repozytorium na Github czy coś? Bardzo chciałbym zobaczyć działający przykład
netpoetica
7
@Arne: Nie odrzucasz odpowiedzi, ponieważ nie jest najlepsza. Negujesz odpowiedź, ponieważ nie jest pomocna. Dopóki działa, ta odpowiedź jest nadal pomocna, nawet jeśli istnieją lepsze rozwiązania.
Graeme Perrow
Dobra wiadomość, Go skompiluje teraz cpp, więc plik makefile nie jest już wymagany. Opakowania unsafe.Pointer nie działały dla mnie. Skompilowana dla mnie niewielka modyfikacja: play.golang.org/p/hKuKV51cRpgo test powinno działać bez pliku makefile
Drew
47
Wygląda na to, że obecnie SWIG jest najlepszym rozwiązaniem na to:
Obsługuje dziedziczenie, a nawet pozwala na podklasę klasy C ++ za pomocą struktury Go, więc gdy nadpisane metody są wywoływane w kodzie C ++, kod Go jest uruchamiany.
Sekcja o C ++ w Go FAQ została zaktualizowana i teraz wspomina o SWIG i nie mówi już „ ponieważ Go jest zbierające śmieci, byłoby to nierozsądne, przynajmniej naiwnie ”.
Nie możesz jeszcze z tego, co przeczytałem w FAQ :
Czy programy Go łączą się z programami C / C ++?
Istnieją dwie implementacje kompilatora Go, gc (program 6g i przyjaciele) i gccgo. Gc używa innej konwencji wywoływania i konsolidatora i dlatego może być łączony tylko z programami w C używającymi tej samej konwencji. Jest taki kompilator C, ale nie ma kompilatora C ++. Gccgo to front-end GCC, który można ostrożnie łączyć z programami C lub C ++ skompilowanymi przez GCC.
Program cgo zapewnia mechanizm „interfejsu funkcji obcych”, który umożliwia bezpieczne wywoływanie bibliotek C z kodu Go. SWIG rozszerza tę możliwość na biblioteki C ++.
Poniższy przykład stworzyłem na podstawie odpowiedzi Scotta Walesa . Przetestowałem to w uruchomionej gowersji macOS High Sierra 10.13.3 go1.10 darwin/amd64.
(1) Kod library.hppinterfejsu API C ++, który chcemy wywołać.
#pragma once
classFoo{public:Foo(intvalue);~Foo();intvalue()const;private:int m_value;};
Przykładowy program mogę uruchomić w następujący sposób:
$ 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)
Ważny
Komentarze powyżej import "C"w goprogramie NIE SĄ OPCJONALNE . Musisz umieścić je dokładnie tak, jak pokazano, aby cgowiedzieć, który nagłówek i bibliotekę załadować, w tym przypadku:
Wygląda na to, że to jedno z wczesnych pytań o Golang. Jednocześnie odpowiada, aby nigdy nie aktualizować. W ciągu tych trzech do czterech lat opublikowano zbyt wiele nowych bibliotek i postów na blogu. Poniżej znajduje się kilka linków, które uznałem za przydatne.
Podczas korzystania z kompilatora gcc Go, gccgo, mówi się o interoperacyjności między C i Go . Istnieją jednak ograniczenia zarówno co do współdziałania, jak i zaimplementowanego zestawu funkcji Go podczas korzystania z gccgo (np. Ograniczone gorutyny, brak czyszczenia pamięci).
1. Stworzyć język bez możliwości ręcznego zarządzania pamięcią, 2. Usunąć czyszczenie pamięci? Czy tylko ja drapie się w tym w głowę?
György Andrasek
2
Kroczysz tu po niezbadanym terenie. Oto przykład Go do wywoływania kodu w C, być może możesz zrobić coś takiego po przeczytaniu o zniekształcaniu nazw w C ++ i konwencjach wywoływania oraz wielu próbach i błędach.
Problem polega na tym, że zgodna implementacja nie musi umieszczać twoich klas w skompilowanym pliku .cpp. Jeśli kompilator może zoptymalizować istnienie klasy, o ile program zachowuje się bez niej w ten sam sposób, można go pominąć w wyjściowym pliku wykonywalnym.
C ma ustandaryzowany interfejs binarny. Dzięki temu będziesz mógł wiedzieć, że Twoje funkcje są eksportowane. Ale C ++ nie ma za sobą takiego standardu.
Zabawne, jak wiele szerszych kwestii pogłębiło to ogłoszenie. Dan Lyke przeprowadził bardzo zabawną i przemyślaną dyskusję na swojej stronie internetowej Flutterby na temat rozwijania standardów międzyprocesowych jako sposobu na ładowanie nowych języków (i innych konsekwencji, ale to jest tutaj istotne).
W istocie „Jeśli import„ C ”jest bezpośrednio poprzedzony komentarzem, komentarz ten, zwany preambułą, jest używany jako nagłówek podczas kompilowania części C pakietu. Na przykład: „
źródło: https://golang.org/cmd/cgo/
Odpowiedzi:
Aktualizacja: Udało mi się połączyć małą testową klasę C ++ z Go
Jeśli otoczysz kod C ++ interfejsem C, powinieneś móc wywołać swoją bibliotekę za pomocą cgo (zobacz przykład gmp w
$GOROOT/misc/cgo/gmp
).Nie jestem pewien, czy idea klasy w C ++ jest naprawdę wyrażalna w Go, ponieważ nie ma dziedziczenia.
Oto przykład:
Mam klasę C ++ zdefiniowaną jako:
którego chcę używać w Go. Użyję interfejsu C.
(Używam struktury
void*
zamiast C, więc kompilator zna rozmiar Foo)Wdrożenie to:
po wykonaniu tego wszystkiego plik Go to:
Plik makefile, którego użyłem do skompilowania tego, to:
Spróbuj to przetestować z:
Musisz zainstalować udostępnioną bibliotekę za pomocą polecenia make install, a następnie uruchomić make test. Oczekiwany wynik to:
źródło
go test
powinno działać bez pliku makefileWygląda na to, że obecnie SWIG jest najlepszym rozwiązaniem na to:
http://www.swig.org/Doc2.0/Go.html
Obsługuje dziedziczenie, a nawet pozwala na podklasę klasy C ++ za pomocą struktury Go, więc gdy nadpisane metody są wywoływane w kodzie C ++, kod Go jest uruchamiany.
Sekcja o C ++ w Go FAQ została zaktualizowana i teraz wspomina o SWIG i nie mówi już „ ponieważ Go jest zbierające śmieci, byłoby to nierozsądne, przynajmniej naiwnie ”.
źródło
Nie możesz jeszcze z tego, co przeczytałem w FAQ :
źródło
Począwszy od go1.2 +, cgo automatycznie włącza i kompiluje kod C ++:
http://golang.org/doc/go1.2#cgo_and_cpp
źródło
Poniższy przykład stworzyłem na podstawie odpowiedzi Scotta Walesa . Przetestowałem to w uruchomionej
go
wersji macOS High Sierra 10.13.3go1.10 darwin/amd64
.(1) Kod
library.hpp
interfejsu API C ++, który chcemy wywołać.(2) Kod
library.cpp
, implementacja C ++.(3) Kod
library-bridge.h
mostu potrzebny do udostępnieniaC
interfejsu API zaimplementowanego w programieC++
, abygo
móc go używać.(4) Kod
library-bridge.cpp
implementacji mostu.(5) Na koniec
library.go
program go wywołujący API C ++.Używając następującego pliku Makefile
Przykładowy program mogę uruchomić w następujący sposób:
Ważny
Komentarze powyżej
import "C"
wgo
programie NIE SĄ OPCJONALNE . Musisz umieścić je dokładnie tak, jak pokazano, abycgo
wiedzieć, który nagłówek i bibliotekę załadować, w tym przypadku:Link do repozytorium GitHub z pełnym przykładem .
źródło
Wygląda na to, że to jedno z wczesnych pytań o Golang. Jednocześnie odpowiada, aby nigdy nie aktualizować. W ciągu tych trzech do czterech lat opublikowano zbyt wiele nowych bibliotek i postów na blogu. Poniżej znajduje się kilka linków, które uznałem za przydatne.
SWIG and Go
Wywołanie kodu C ++ z Go z SWIG
Porównywanie języków, C ++ i Go
GoForCPPProgrammers
źródło
Podczas korzystania z kompilatora gcc Go, gccgo, mówi się o interoperacyjności między C i Go . Istnieją jednak ograniczenia zarówno co do współdziałania, jak i zaimplementowanego zestawu funkcji Go podczas korzystania z gccgo (np. Ograniczone gorutyny, brak czyszczenia pamięci).
źródło
Kroczysz tu po niezbadanym terenie. Oto przykład Go do wywoływania kodu w C, być może możesz zrobić coś takiego po przeczytaniu o zniekształcaniu nazw w C ++ i konwencjach wywoływania oraz wielu próbach i błędach.
Jeśli nadal masz ochotę spróbować, powodzenia.
źródło
Problem polega na tym, że zgodna implementacja nie musi umieszczać twoich klas w skompilowanym pliku .cpp. Jeśli kompilator może zoptymalizować istnienie klasy, o ile program zachowuje się bez niej w ten sam sposób, można go pominąć w wyjściowym pliku wykonywalnym.
C ma ustandaryzowany interfejs binarny. Dzięki temu będziesz mógł wiedzieć, że Twoje funkcje są eksportowane. Ale C ++ nie ma za sobą takiego standardu.
źródło
Może być konieczne dodanie
-lc++
doLDFlags
for Golang / CGo, aby rozpoznać potrzebę biblioteki standardowej.źródło
Zabawne, jak wiele szerszych kwestii pogłębiło to ogłoszenie. Dan Lyke przeprowadził bardzo zabawną i przemyślaną dyskusję na swojej stronie internetowej Flutterby na temat rozwijania standardów międzyprocesowych jako sposobu na ładowanie nowych języków (i innych konsekwencji, ale to jest tutaj istotne).
źródło
Można to osiągnąć za pomocą polecenia cgo.
W istocie „Jeśli import„ C ”jest bezpośrednio poprzedzony komentarzem, komentarz ten, zwany preambułą, jest używany jako nagłówek podczas kompilowania części C pakietu. Na przykład: „
źródło: https://golang.org/cmd/cgo/
źródło