Подтвердить что ты не робот

Строение и динамическое связывание из двоичного

Моя проблема заключается в следующем:

  • У меня есть двоичный файл go на машине.
  • Из этого двоичного файла мне нужно скомпилировать внешний .go файл
  • После компиляции мне нужно связать скомпилированный файл go в текущем двоичном файле, чтобы я мог использовать только что скомпилированный код go.

Считаете ли вы, что это возможно?

Я сделал несколько исследований, и это кажется невозможным, но я мог бы что-то упустить.

Спасибо:)

Первый бинарный код будет содержать что-то вроде

func main() {
    // Here I need to compile an external go file (or package) which contains
    // The definition of runFoo()

    // Once the file/package is compiled and linked I need to call the compiled code
    runFoo()

    // Continue the execution process normally here
}
4b9b3361

Ответ 1

Обновление: Теперь можно сделать это в mainline Go, см. Перейти к режимам выполнения

Из Заметки о выпуске Go 1.5:

Только для архитектуры amd64 у компилятора есть новая опция, -dynlink, которая помогает динамической компоновке, поддерживая ссылки на символы Go, определенные во внешних общих библиотеках.

Старый ответ (полезное обсуждение других опций):

В настоящее время невозможно создать динамически связанные библиотеки * в главной строке Go. Об этом говорили некоторые, поэтому вы можете увидеть поддержку в будущем. Тем не менее, существует проект сторонней стороны, называемый goandriod, который нуждается в той же функциональности, в которой вы нуждаетесь, поэтому они поддерживают исправления, которые должны позволять вам исправлять официальную базу кодов Go для поддержки поддержки динамической связанной поддержки.

Если вы хотите использовать стандартное время выполнения Go, я бы порекомендовал одно из следующих. Вызовите свою программу Go из своей другой программы и общайтесь с помощью:

  • Трубы для связи
  • Разъем домена UNIX
  • Разделенная область разделяемой памяти.

Каждый последовательный параметр будет прилагать больше усилий для настройки, быть более специфичным для платформы, но потенциально более мощным, чем предыдущий.

* Примечание: Это DLL в мире Windows и .so файлы в мире UNIX/Linux.

Ответ 2

Возможность создания разделяемых библиотек будет в Go 1.5 в августе 2015 года.

От "" Голосование "" Эндрю Джерранн":

Общие библиотеки

Go 1.5 может создавать общие библиотеки Go, которые могут быть использованы Go программы.

Создайте стандартную библиотеку в виде разделяемых библиотек:

$ go install -buildmode=shared std

Создайте программу "Hello, world", которая связывает библиотеки:

$ go build -linkshared hello.go
$ ls -l hello
-rwxr-xr-x 1 adg adg 13926 May 26 02:13 hello

Go 1.5 также может создавать программы Go в качестве архивных файлов C (для статических ссылки) или разделяемые библиотеки (для динамической компоновки), которые могут быть потребляемых программами C.

[Смотрите:] golang.org/s/execmodes

¹ Примечание. gccgo уже некоторое время поддерживала ограниченную поддержку, Go 1.5 будет в первый раз поддерживаться обычными инструментами сборки go.

Ответ 3

Это очень возможно, вы даже можете скомпилировать его как родную общую библиотеку

go build -buildmode=c-shared goc.go 

# file goc
goc: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV),
dynamically linked, 
BuildID[sha1]=f841e63ee8e916d7848ac8ee50d9980642b3ad86, 
not stripped

nm -D - определено только. /goc | grep "T"

0004ebe8 T _cgoexp_f88ec80374ab_PrintInt
000a6178 T _cgo_panic
0004e954 T _cgo_sys_thread_start
000a48c8 T _cgo_topofstack
0004e88c T _cgo_wait_runtime_init_done
000a61a4 T crosscall2
0004ebc8 T crosscall_arm1
0004e7b0 T fatalf
00102648 T _fini
0004e544 T _init
0004e76c T PrintInt
0004ebe4 T __stack_chk_fail_local
0004eb5c T x_cgo_free
0004ea60 T x_cgo_init
0004eb24 T x_cgo_malloc
0004e8e0 T x_cgo_notify_runtime_init_done
0004eb14 T x_cgo_setenv
0004e820 T x_cgo_sys_thread_create
0004eb64 T x_cgo_thread_start
0004eb20 T x_cgo_unsetenv

так (протестировано на go 1.5.1 linux/arm)

goc.go:

package main

import (
    "C"
    "fmt"
)

//export PrintInt
func PrintInt(x int) {
    fmt.Println(x)
}

// http://stackoverflow.com/questions/32215509/using-go-code-in-an-existing-c-project
// go build -buildmode=c-archive goc.go
// go build -buildmode=c-shared goc.go 

// https://groups.google.com/forum/#!topic/golang-nuts/1oELh6joLQg
// Trying it on windows/amd64, looks like it isn't supported yet.  Is this planned for the 1.5 release? 
// It will not be in the 1.5 release.
// It would be nice if somebody worked on it for 1.6.
// https://golang.org/s/execmodes

// http://stackoverflow.com/questions/19431296/building-and-linking-dynamically-from-a-go-binary
// go build -linkshared hello.g
// go install -buildmode=shared std



func main() {
    fmt.Println("Hello world")
}