Go Pluginでプラグインプログラミングを簡単に実装する方法
前書き
プラグインというと、馴染みのない方も多いのではないでしょうか。一般的に、プラグインにはいくつかの利点があり、1つはプログラムの拡張性を高め、機能を充実させることである。小さな更新は、プログラム全体を再ダウンロードする必要がある場合はさらに、それはまた、ホットアップデート、いくつかの大規模なアプリケーション、簡単にインストール手順の数GBを達成することができる、この時間は、我々は頻繁に更新モジュールのプラグインを更新できるように、更新時にのみ小さな更新ファイルをダウンロードする必要があることです。たとえば、通常私たちのChromeブラウザは、より多くの機能を達成するためにブラウザを拡張することができますいくつかのプラグインがロードされますが、また、柔軟性をインストールおよびアンインストールします。
Golangはバージョン1.8以降、ファイルを動的にロードしてプラグインを実装するプラグインメカニズムを提供していますが、これはあまり成熟していませんが、特定の状況下ではまだ非常に便利です。
<ブロッククオート現在のところ、プラグインはLinux、FreeBSD、macOSでのみサポートされています。
1. クイックスタート
プラグインのコードは通常のコードと変わりなく、コンパイルが異なるだけですが、要件として、メインパッケージは1つだけである必要があります。
def ss(a,b):
pass
ss(1,2,b=1)
go build -buildmode=plugin でコンパイルするとsoファイルができますが、このファイルはどのように使うのですか?
簡単です、3つのステップで。
1. まずsoファイルを開き、すでにプラグインが開かれている場合は、既存のプラグインを返します
2. 呼び出す必要のある変数や関数を探すにはLookupを使用し、名前は大文字で始まる必要があります。
3. アサーション後の呼び出し
func main() {
//open and load the plugin, the parameter is the location where the plugin is stored, it can be a relative path
open, err := plugin.Open("/home/jwang/Documents/plg.so")
if err ! = nil {
panic(err)
}
//lookup identifier
lookup, err := open.Lookup("GetName")
if err ! = nil {
panic(err)
}
res := lookup.(func() string)()
fmt.Printf("%v\n", res)
name, err := open.Lookup("Name")
if err ! = nil {
panic(err)
}
fmt.Printf("%v\n", *name.(*string))
}
上記のコードからわかるように、このプラグインは非常に平易で使いやすいものです。
一般に、プラグインを実装するためには、あらかじめいくつかのインターフェースを定義しておき、プラグインにそれを実装させることで一貫性を持たせることができますが、インターフェース定義はプラグインパッケージやコールパッケージの内部には書けません。そこで、インターフェイスの定義を書き込むための特別なパブリックパッケージを定義し、プラグインパッケージと呼び出しパッケージの両方がそれを参照できるようにする必要があるのです。
2. 注意事項
このプラグインソリューションが未熟な理由は、主に以下のようなメインプログラムとプラグインプログラムの間の強い依存関係にあります。
1. コンパイルされたGOのバージョンは同一でなければならない
2. 両者が依存するパブリックサードパーティライブラリのバージョンが同一であること
3. GOPATHも一致していなければならないが、これはコンパイル時にtrimpathパラメータを使用することで解決できる
4. プラグインはロード後にアンインストールできない
これらの問題は、いつまで経っても公式に解決されない、あるいは解決できないようです。要するに、Goプラグインは今のところほとんど用途がないのです。何しろ、Webプログラミング言語である以上、コンテナ化が流行る環境でプログラムを更新するのは、特別な必要がない限り、簡単なことなのですから。
まとめ
Go Pluginを使ったプラグインプログラミングの記事は以上です。Go Plugin のプラグインプログラミングの詳細については、過去の記事を検索するか、以下の記事を引き続きご覧ください。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン