В техническом докладе SWIG был очень кратко упомянут, что-то вроде: "... пока мы не сделаем глоток ..."
StackedCrooked
1
@Matt: Вероятно, он хочет использовать существующую библиотеку C ++ без необходимости переносить ее на C или Go. Я хотел то же самое.
Грэм Перроу
Я не могу вспомнить ни одной достойной библиотеки, доступной для C ++, а не для C. Я хотел бы знать, что вы имеете в виду.
Мэтт Джоунер
13
@Matt: Одним из примеров является библиотека Boost, и есть тысячи других полезных библиотек C ++. Но, может быть, я просто кормлю тролля здесь ...
Фрэнк
@Matt: в моем случае я хотел создать интерфейс Go для нашей существующей клиентской библиотеки, но в основном это C ++. Портировать его на C или Go просто не вариант.
Грэм Перроу
Ответы:
154
Обновление: мне удалось связать небольшой тестовый класс C ++ с Go
Если вы закроете свой код C ++ интерфейсом C, вы сможете вызывать вашу библиотеку с помощью cgo (см. Пример gmp in $GOROOT/misc/cgo/gmp).
Я не уверен, что идея класса в C ++ действительно выразима в Go, так как она не имеет наследования.
Будьте осторожны с этим, я понятия не имею, что может случиться с памятью, если вы отправите ее между двумя языками.
Скотт Уэльс
11
Должен сказать, этот пример напоминает мне, почему я хочу написать чистый Go. Посмотрите, насколько больше и страшнее сторона C ++. Ик.
Джефф Аллен
@ ScottWales, есть ли вероятность, что вы поместили это в репозиторий на Github или что-нибудь еще? Я хотел бы увидеть рабочий пример
netpoetica
7
@Arne: Вы не отрицаете ответ, потому что он не самый лучший. Вы отрицаете ответ, потому что он не помогает. Пока он работает, этот ответ по-прежнему полезен, даже если есть лучшие решения.
Грэм Перроу
Хорошие новости, Go теперь скомпилирует cpp, поэтому make-файл больше не требуется. Небезопасные. Обертки указателя у меня не сработали. Небольшая модификация, скомпилированная для меня: play.golang.org/p/hKuKV51cRpgo test должна работать без make-файла
Дрю
47
Похоже, что в настоящее время SWIG является лучшим решением для этого:
Он поддерживает наследование и даже позволяет создавать подклассы класса C ++ со структурой Go, поэтому при вызове переопределенных методов в коде C ++ код Go запускается.
Раздел о C ++ в Go FAQ обновлен, и теперь в нем упоминается SWIG и больше не говорится, что « поскольку Go является сборщиком мусора, это будет неразумно, по крайней мере наивно ».
Я хотел бы, чтобы был способ поднять это. Другие ответы устарели. Плюс SWIG версировал swig.org/Doc3.0/Go.html
dragonx
34
Вы не можете еще совсем из того, что я прочитал в FAQ :
Связаны ли программы Go с программами C / C ++?
Существует две реализации компилятора Go: gc (программа 6g и друзья) и gccgo. Gc использует другое соглашение о вызовах и компоновщик и поэтому может быть связано только с программами на Си, использующими то же соглашение. Существует такой компилятор C, но нет компилятора C ++. Gccgo - это интерфейс GCC, который может быть осторожно связан с программами C или C ++, скомпилированными GCC.
Программа cgo предоставляет механизм для «интерфейса внешних функций», позволяющий безопасно вызывать библиотеки C из кода Go. SWIG расширяет эту возможность для библиотек C ++.
Я создал следующий пример на основе ответа Скотта Уэльса . Я протестировал его в MacOS High Sierra 10.13.3 под управлением goверсииgo1.10 darwin/amd64 .
(1) Код для library.hppC ++ API, который мы стремимся вызвать.
#pragma once
classFoo{public:Foo(intvalue);~Foo();intvalue()const;private:int m_value;};
Я могу запустить пример программы следующим образом:
$ 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)
Важный
Комментарии выше import "C"в goпрограмме НЕ ДОПОЛНИТЕЛЬНЫЕ . Вы должны поместить их точно так, как показано, чтобы они cgoзнали, какой заголовок и библиотеку загружать, в этом случае:
Похоже, это один из самых ранних вопросов о Голанге. И в то же время ответы никогда не обновлять. За эти три-четыре года появилось слишком много новых библиотек и постов в блогах. Ниже приведены несколько ссылок, которые мне показались полезными.
Говорят о совместимости между C и Go при использовании компилятора gcc Go, gccgo. Однако при использовании gccgo существуют ограничения как на функциональную совместимость, так и на реализованный набор функций Go (например, ограниченные процедуры, сборка мусора отсутствует).
1. Сделать язык без средств для ручного управления памятью, 2. Удалить сборку мусора? Я единственный, кто царапает мне голову от этого?
György Andrasek
2
Ты идешь по неизведанной территории. Вот пример Go для вызова кода на C, возможно, вы можете сделать что-то подобное после прочтения правил сортировки имен C ++ и соглашений о вызовах, а также множества проб и ошибок.
Проблема здесь в том, что совместимая реализация не должна помещать ваши классы в файл компиляции .cpp. Если компилятор может оптимизировать существование класса, при условии, что программа ведет себя так же без него, его можно исключить из выходного исполняемого файла.
C имеет стандартизированный двоичный интерфейс. Поэтому вы сможете узнать, что ваши функции экспортируются. Но в C ++ такого стандарта нет.
Забавно, сколько более широких вопросов это объявление вскопало. Дэн Лайк на своем веб-сайте Flutterby провел очень занимательную и вдумчивую дискуссию о разработке межпроцессных стандартов как способа начальной загрузки новых языков (и других разветвлений, но это уместно здесь).
По сути, «если импорту« C »предшествует комментарий, этот комментарий, называемый преамбулой, используется в качестве заголовка при компиляции частей C пакета. Например: '
источник: https://golang.org/cmd/cgo/
Ответы:
Обновление: мне удалось связать небольшой тестовый класс C ++ с Go
Если вы закроете свой код C ++ интерфейсом C, вы сможете вызывать вашу библиотеку с помощью cgo (см. Пример gmp in
$GOROOT/misc/cgo/gmp
).Я не уверен, что идея класса в C ++ действительно выразима в Go, так как она не имеет наследования.
Вот пример:
У меня есть класс C ++, определенный как:
который я хочу использовать в Go. Я буду использовать интерфейс C
(Я использую
void*
вместо структуры C, чтобы компилятор знал размер Foo)Реализация:
со всем, что сделано, файл Go:
Makefile, который я использовал для компиляции этого, был:
Попробуйте проверить это с:
Вам нужно установить совместно используемую библиотеку с помощью make install, а затем запустить make test. Ожидаемый результат:
источник
go test
должна работать без make-файлаПохоже, что в настоящее время SWIG является лучшим решением для этого:
http://www.swig.org/Doc2.0/Go.html
Он поддерживает наследование и даже позволяет создавать подклассы класса C ++ со структурой Go, поэтому при вызове переопределенных методов в коде C ++ код Go запускается.
Раздел о C ++ в Go FAQ обновлен, и теперь в нем упоминается SWIG и больше не говорится, что « поскольку Go является сборщиком мусора, это будет неразумно, по крайней мере наивно ».
источник
Вы не можете еще совсем из того, что я прочитал в FAQ :
источник
Начиная с go1.2 +, cgo автоматически включает и компилирует код C ++:
http://golang.org/doc/go1.2#cgo_and_cpp
источник
Я создал следующий пример на основе ответа Скотта Уэльса . Я протестировал его в MacOS High Sierra 10.13.3 под управлением
go
версииgo1.10 darwin/amd64
.(1) Код для
library.hpp
C ++ API, который мы стремимся вызвать.(2) Код для
library.cpp
реализации C ++.(3) Код для
library-bridge.h
моста, необходимого для предоставленияC
API, реализованного в нем,C++
чтобы егоgo
можно было использовать.(4) Код для
library-bridge.cpp
реализации моста.(5) Наконец,
library.go
программа go, вызывающая API C ++.Используя следующий Makefile
Я могу запустить пример программы следующим образом:
Важный
Комментарии выше
import "C"
вgo
программе НЕ ДОПОЛНИТЕЛЬНЫЕ . Вы должны поместить их точно так, как показано, чтобы ониcgo
знали, какой заголовок и библиотеку загружать, в этом случае:Ссылка на репозиторий GitHub с полным примером .
источник
Похоже, это один из самых ранних вопросов о Голанге. И в то же время ответы никогда не обновлять. За эти три-четыре года появилось слишком много новых библиотек и постов в блогах. Ниже приведены несколько ссылок, которые мне показались полезными.
SWIG and Go
Вызов кода C ++ из Go с помощью SWIG
О сравнении языков, C ++ и Go
GoForCPPProgrammers
источник
Говорят о совместимости между C и Go при использовании компилятора gcc Go, gccgo. Однако при использовании gccgo существуют ограничения как на функциональную совместимость, так и на реализованный набор функций Go (например, ограниченные процедуры, сборка мусора отсутствует).
источник
Ты идешь по неизведанной территории. Вот пример Go для вызова кода на C, возможно, вы можете сделать что-то подобное после прочтения правил сортировки имен C ++ и соглашений о вызовах, а также множества проб и ошибок.
Если вам все еще хочется попробовать, удачи.
источник
Проблема здесь в том, что совместимая реализация не должна помещать ваши классы в файл компиляции .cpp. Если компилятор может оптимизировать существование класса, при условии, что программа ведет себя так же без него, его можно исключить из выходного исполняемого файла.
C имеет стандартизированный двоичный интерфейс. Поэтому вы сможете узнать, что ваши функции экспортируются. Но в C ++ такого стандарта нет.
источник
Возможно, вам придется добавить
-lc++
вLDFlags
Golang / CGo для того, чтобы распознать потребность в стандартной библиотеке.источник
Забавно, сколько более широких вопросов это объявление вскопало. Дэн Лайк на своем веб-сайте Flutterby провел очень занимательную и вдумчивую дискуссию о разработке межпроцессных стандартов как способа начальной загрузки новых языков (и других разветвлений, но это уместно здесь).
источник
Это может быть достигнуто с помощью команды cgo.
По сути, «если импорту« C »предшествует комментарий, этот комментарий, называемый преамбулой, используется в качестве заголовка при компиляции частей C пакета. Например: '
источник: https://golang.org/cmd/cgo/
источник