15

タイトルが示すように、実行時にのみ利用可能な情報に基づいて、Go パッケージを動的にロードする (またはロードしない) 必要があります。

目的は、ユーザーが新しいネイティブ スクリプト コマンドを追加するカスタム パッケージを介してプログラムを拡張できるようにすることです。現在、新しいコマンドを追加したり、一部のコマンドを禁止したりするたびに、プログラムを編集して再コンパイルする必要がありますが、何らかの種類の dll などを作成できる場合は、検索してロードする「インポート」スクリプト コマンドを作成できます。名前付きコマンド ライブラリ。

興味深いことに、問題のプログラムは、私があらゆる種類のものに使用するカスタム コマンド ベースのスクリプト ライブラリです。

事前に検索を行ったところ、結果は良くないように見えましたが、明確なノーが見つかりませんでした。

4

3 に答える 3

15

Go はまだ動的ライブラリをサポートしていません。Elias Naur は最近いくつかのパッチを公開しましたが、まだレビューされておらず、Go 1.2 に含まれる可能性は低いです。Google グループでディスカッションを読むことができます。

私の知る限り、これがそのトピックに関する最新の議論です。

ただし、別のアプローチがあります。別のプロセスでプラグインを開始し、net/rpcパッケージを使用してメイン アプリと通信できます。これにより、個別のプラグインを動的に開始/停止/再コンパイルすることもでき、悪いプラグインがプログラムをクラッシュさせないという利点があります。Go はネットワーク通信に優れているので、それをうまく利用する必要があります。

プログラムを編集して再コンパイルする必要がありますが、

また、(fsnotify を使用して) 現在のディレクトリの変更を監視し、「go build」を実行してからプログラムを再起動する小さなスクリプトを作成することも検討できます。私はローカル開発中にいくつかの Web プロジェクトでこのアプローチを使用しており、正常に動作します。コンパイル時間を観察することはできず、ブラウザー ウィンドウの切り替えと更新は非常に高速です。私の Python 開発サイクルでは、変更のたびにインタープリターを再起動し、すべてのモジュールを再インポートする必要があります (大規模なプロジェクトではかなりの時間がかかる可能性があります!)、Go と比較すると非常にぎこちなく感じます。

于 2013-08-14T18:02:44.603 に答える
4

これは Go 1.8 でサポートされています。現時点ではかなり未熟で初歩的ですが、ようやく可能になりました。

また、Mateusz Gajewski のgo-bind-pluginプロジェクトは、ロードされたプラグインの使用を簡素化するので、興味深いかもしれません。

プラグイン パッケージのドキュメントから:

たとえば、次のように定義されたプラグイン

package main

// // No C code needed.
import "C"

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 interface{}
于 2017-02-24T16:59:44.100 に答える
0

Go 用の dlopen-packageがあります。つまり、少なくとも、共有ライブラリ (DLL) を Go プログラムにロードできます。おそらく、C、C++ で拡張機能をコーディングする必要があります。または、共有ライブラリを生成できるツールがある他の何か。

于 2016-08-05T18:32:10.463 に答える