0Pricing
Go Academy · レッスン

動的ロードとシンボル

実行時にプラグインをロードし、エクスポートされたシンボルを呼び出します。

「動的ロードとシンボル」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

plugin.Open

plugin.Open(path)はコンパイル済みの.soファイルを読み込みます。プラグインのinit()関数とパッケージレベルの変数を初期化し、シンボルを利用可能にします。

p, err := plugin.Open("./plugins/mymodule.so")
if err != nil { log.Fatalf("load: %v", err) }

p.Lookup

p.Lookup(name)は名前でエクスポートされたシンボルを検索します。anyを返すため、期待する型に型アサーションします。

sym, err := p.Lookup("NewProcessor")
if err != nil { log.Fatalf("lookup: %v", err) }
fn, ok := sym.(func() Processor)
if !ok { log.Fatal("wrong type") }

複数のプラグインの読み込み

ディレクトリ内の各.soを読み込み、ループで登録します:

entries, _ := os.ReadDir("./plugins")
for _, e := range entries {
    if !strings.HasSuffix(e.Name(), ".so") { continue }
    p, err := plugin.Open("./plugins/" + e.Name())
    if err != nil { log.Printf("skip %s: %v", e.Name(), err); continue }
    loadPlugin(p)
}

ファクトリ関数パターン

プラグインは値ではなくファクトリ関数(NewXxx() Processor)をエクスポートするため、ホストは呼び出しごとに新しいインスタンスを取得できます:

sym, _ := p.Lookup("NewProcessor")
factory := sym.(func() Processor)
proc := factory() // new instance

検索時のエラーハンドリング

Lookupエラーは、シンボルがエクスポートされていないか、名前が間違っていることを示します。適切に処理し、プラグインをスキップするか、ログを記録して他のプラグインの読み込みを続行します。

plugin.Openはべき等です

同じパスに対してplugin.Openを2回呼び出すと、同じプラグインが返されます。プラグインは一度だけ初期化されます。

遅延読み込み

起動時間を短縮するため、起動時ではなく必要になった時点(初回使用時)にプラグインを読み込みます。プラグインごとにsync.Onceを使用し、必ず一度だけ読み込まれるようにします。

var mu sync.Mutex
var loaded = map[string]*plugin.Plugin{}

func getPlugin(path string) (*plugin.Plugin, error) {
    mu.Lock(); defer mu.Unlock()
    if p, ok := loaded[path]; ok { return p, nil }
    p, err := plugin.Open(path)
    if err != nil { return nil, err }
    loaded[path] = p
    return p, nil
}

シンボルの命名規則

エクスポートするシンボルには、先頭を大文字にしたCamelCaseの名前を使用します(Goの可視性ルールが適用されます)。一般的な規約では、メインの値にはPlugin、ファクトリにはNewを使用します。

プラグインのパニック処理

プラグインがパニックを発生させた場合、ホストのrecoverミドルウェアで捕捉できることがありますが、プラグインのgoroutineが未定義の状態になる可能性があります。ログを記録してプラグインをスキップし、再試行は行わないでください。

プラグインメタデータの検証

読み込み後、メタデータシンボル(例:PluginVersion string)を確認し、登録前に互換性を検証します:

ver, _ := p.Lookup("PluginVersion")
if *ver.(*string) != expectedVersion { log.Fatal("incompatible") }

クイックチェック

同じパスを指定してplugin.Openを2回呼び出すと、どうなりますか?

まとめ:動的な読み込みとシンボル

重要なポイント:

  • plugin.Openで.soを読み込み、p.Lookupはanyを返すため型アサーションします
  • プラグインシステムでは、ディレクトリ内のプラグインをループで読み込みます
  • plugin.Openはべき等で、init()はパスごとに一度だけ実行されます
  • 新しいインスタンスを取得するには、値のシンボルよりファクトリ関数を優先します

よくある質問

「動的ロードとシンボル」レッスンは無料ですか?

はい。「動的ロードとシンボル」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「動的ロードとシンボル」で何を学びますか?

実行時にプラグインをロードし、エクスポートされたシンボルを呼び出します。 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「動的ロードとシンボル」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Goのpluginパッケージの基本
  2. プラグインインターフェースの設計
  3. 動的ロードとシンボル
  4. 代替手段:HashiCorp go-plugin
← Go Academyに戻る