Spec-Zone.ru › Go

Пакет plugin

  • import "plugin"
  • Обзор
  • Индекс

Обзор

Пакет plugin реализует загрузку и разрешение символов для плагинов Go.

Плагин — это пакет Go, содержащий экспортированные функции и переменные, скомпилированные с помощью:

go build -buildmode=plugin

При первом открытии плагина вызываются функции инициализации всех пакетов, которые ещё не входят в состав программы. Функция main не выполняется. Плагин инициализируется только один раз и не может быть закрыт.

Предупреждения

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

Однако механизм плагинов имеет много существенных недостатков, которые следует тщательно учитывать при проектировании. Например:

  • Плагины в настоящее время поддерживаются только на Linux, FreeBSD и macOS, что делает их непригодными для приложений, предназначенных для переноса.

  • Приложения, использующие плагины, могут потребовать тщательной конфигурации, чтобы убедиться, что различные части программы доступны в нужном месте в файловой системе (или образе контейнера). Напротив, развертывание приложения, состоящего из одного статического исполняемого файла, является простым.

  • Анализ инициализации программы становится сложнее, когда некоторые пакеты могут не быть инициализированы до тех пор, пока приложение не начнёт выполняться.

  • Ошибки в приложениях, загружающих плагины, могут быть использованы злоумышленником для загрузки опасных или ненадежных библиотек.

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

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

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

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

Индекс

  • тип Plugin
  • функция Open(path string) (*Plugin, error)
  • функция (p *Plugin) Lookup(symName string) (Symbol, error)
  • тип Symbol

Файлы пакета

plugin.go plugin_dlopen.go

тип Plugin 1.8

Plugin — загруженный плагин Go.

type Plugin struct {
    // contains filtered or unexported fields
}

функция Open 1.8

func Open(path string) (*Plugin, error)

Open открывает плагин Go. Если путь уже был открыт, то возвращается существующий *Plugin. Безопасно для одновременного использования несколькими горутинами.

функция (*Plugin) Lookup 1.8

func (p *Plugin) Lookup(symName string) (Symbol, error)

Lookup ищет символ с именем symName в плагине p. Символ — это любая экспортированная переменная или функция. Возвращает ошибку, если символ не найден. Безопасно для одновременного использования несколькими горутинами.

тип Symbol 1.8

Symbol — указатель на переменную или функцию.

Например, плагин, определённый как

package main

import "fmt"

var V int

func F() { fmt.Printf("Hello, number %d\n", V) }

может быть загружен с помощью функции Open, а затем доступ к экспортированным символам пакета V и F можно получить

p, err := plugin.Open("plugin_name.so")
if err != nil {
	panic(err)
}
v, err := p.Lookup("V")
if err != nil {
	panic(err)
}
f, err := p.Lookup("F")
if err != nil {
	panic(err)
}
*v.(*int) = 7
f.(func())() // prints "Hello, number 7"
type Symbol any

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/plugin/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API