動的ロードとシンボル
実行時にプラグインをロードし、エクスポートされたシンボルを呼び出します。
「動的ロードとシンボル」は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フィードバックを取得できます。ローカル設定は不要です。