2013-05-29 2 views
3

У меня есть проект, где я хотел бы загрузить плагины Go внутри приложения C++.Перейти к общей библиотеке как плагин C++

После многих исследований мне не ясно, поддерживает ли это Go Go или нет. Я столкнулся с большим количеством обсуждений, указывающих на плохую привычку к динамической компоновке, вместо этого, вместо прочтения IPC. Более того, для меня не ясно, связано ли динамическое соединение языком или нет (новая философия Go?).

cgo предоставляет возможность вызова C от Go или Go с C (внутри Go), но не от простого старого C. Или это так?

  • дс, кажется, не поддерживает общую библиотеку (даже если https://code.google.com/p/go/issues/detail?id=256 упоминает он делает)
  • gccgo поддержка Go разделяемые библиотеки, но я не мог заставить его работать (возможно, потому что главная точка входа не в Go ...)
  • SWIG, кажется, не помогло :(

Видимо что-то происходит вверх по течению, а также (https://codereview.appspot.com/7304104/)

main.c

extern void Print(void) __asm__ ("example.main.Print"); 

int main() { 
     Print(); 
} 

print.go

package main 

import "fmt" 

func Print() { 
    fmt.Printf("hello, world\n") 
} 

Makefile:

all: print.o main.c 
     gcc main.c -L. -lprint -o main 

print.o: print.go 
     gccgo -fno-split-stack -fgo-prefix=example -fPIC -c print.go -o print.o 
     gccgo -shared print.o -o libprint.so 

Выход:

/usr/lib/libgo.so.3: undefined reference to `main.main' 
/usr/lib/libgo.so.3: undefined reference to `__go_init_main' 

Есть ли решение для этого? Каков наилучший подход? forking + IPC?

Литература:

+0

рекомендовать решение, чтобы ваша основная программу запустить Go-плагин как внешний процесс, который связан с вашей основной программой с трубкой , Гораздо меньше хлопот и гораздо меньше риска для безопасности. – fuz

ответ

7

Я не думаю, что вы можете вставлять Go в C. Однако вы можете вставлять C в Go и с помощью небольшой программы для заглушки C, которую вы можете назвать C первым, что является следующей лучшей вещью! Cgo определенно поддерживает связь с разделяемыми библиотеками, поэтому, возможно, этот подход будет работать для вас.

Как это

main.go

// Stub go program to call cmain() in C 
package main 

// extern int cmain(void); 
import "C" 

func main() { 
    C.cmain() 
} 

main.c

#include <stdio.h> 

// Defined in Go 
extern void Print(void); 

// C Main program 
int cmain() { 
    printf("Hello from C\n"); 
    Print(); 
} 

print.go

package main 

import "fmt" 

import "C" 

//export Print 
func Print() { 
    fmt.Printf("Hello from Go\n") 
} 

Compile с go build и производит этот выход, когда вы запустите его

Hello from C 
Hello from Go 
+0

Спасибо за ответ! Тем не менее, я предполагаю, что среда выполнения C++ запускается сначала без загрузки плагина. Затем я загружаю плагины Go по мере необходимости (шаблон конфигуратора компонента). Согласно вашему примеру, я не уверен, что вызов C от Go поможет мне. – 3XX0

+0

Вышеупомянутый ответ был предназначен, чтобы показать вам способ сделать код в вопросе работы. Увы, это не решение для использования плагинов Go для расширения C++. Go не создает общие объекты (пока) - он статически связан, поэтому, если вы хотите иметь возможность подключать код Go во время выполнения, вам придется идти с подпроцессами и IPC. Если вы довольны статическим набором плагинов, предварительно скомпилированным в этом случае, вы можете заставить вышеупомянутый метод работать с C++, но вам понадобится немного неизвестной дополнительной магии для запуска среды выполнения C++. –

2

AFAIK, вы не можете скомпилировать пакет Go в общую библиотеку witg 'gc' ATM, это может измениться в будущем. Вероятно, с «gccgo» может быть какой-то «libgo» (предположим, что Go runtime) уже является общей библиотекой. Я предполагаю, что недостающая часть предназначена только для правильной инициализации среды выполнения, которая обычно запускается командой Go.

Эксперт gccgo - I.L. Тейлор, он доступен в списке рассылки голан-орехов почти ежедневно. Я предлагаю спросить его прямо.

PS: Другие проблемы могут включать взаимодействие сборщика мусора Go и памяти процесса (C++) и т. Д. Возможно, я слишком оптимистичен, и это совсем не возможно.

Смежные вопросы