是否可以动态加载Go代码?

是否可以动态加载Go代码?,go,Go,正如标题所说,我希望根据仅在运行时可用的信息动态加载Go包(或不加载) 目标是允许用户通过添加新的本机脚本命令的自定义包扩展程序。目前,每当我添加新命令或想要禁止某些命令时,我都需要编辑程序并重新编译,而如果我可以创建某种dll或类似的东西,那么我可以创建一个“导入”脚本命令来搜索和加载命名的命令库 对于好奇的人来说,这个程序是一个自定义的基于命令的脚本库,我用它来处理各种事情 我提前做了一些搜索,结果看起来不太好,但我找不到明确的号码。Go还不支持动态库。Elias Naur最近发布了一些补丁

正如标题所说,我希望根据仅在运行时可用的信息动态加载Go包(或不加载)

目标是允许用户通过添加新的本机脚本命令的自定义包扩展程序。目前,每当我添加新命令或想要禁止某些命令时,我都需要编辑程序并重新编译,而如果我可以创建某种dll或类似的东西,那么我可以创建一个“导入”脚本命令来搜索和加载命名的命令库

对于好奇的人来说,这个程序是一个自定义的基于命令的脚本库,我用它来处理各种事情


我提前做了一些搜索,结果看起来不太好,但我找不到明确的号码。

Go还不支持动态库。Elias Naur最近发布了一些补丁,但尚未对它们进行审查,因此它们不太可能包含在Go 1.2中。您可以阅读有关谷歌群组的讨论:

据我所知,这是关于这个话题的最新讨论

然而,还有另一种方法。您可以在单独的进程中启动插件,并使用该软件包与主应用程序通信。这也允许你动态地启动/停止/重新编译不同的插件,它的优点是坏插件不会使你的程序崩溃。Go擅长网络沟通,你只需要好好利用它

我需要编辑程序并重新编译


您也可以考虑编写一个小脚本来监视当前目录中的更改(使用FSNOTER),并执行“GO构建”,然后重新启动程序。在本地开发期间,我在一些web项目上使用了这种方法,效果很好。我无法观察任何编译时间,而且我切换和刷新浏览器窗口的速度相当快。在我的Python开发周期中,每次更改都必须重新启动解释器,并重新导入所有模块(在大型项目中可能需要花费大量时间!),与Go相比,我的Python开发周期感觉非常笨拙。

好吧,有一个——因此,至少现在可以将共享库(DLL)加载到Go程序中。。。你可能需要在C、C++或其他一些东西中扩展你的扩展代码,你可以使用它来生成共享库。

< P>在GO 1.8中有支持。目前它还相当不成熟和初级,但它最终是可能的

此外,Mateusz Gajewski的项目可能会引起兴趣,因为它简化了加载插件的使用

从文件中:

例如,定义为

package main

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

import "fmt"

var V int

func F() { fmt.Printf("Hello, number %d\n", V) }
可以使用打开功能加载,然后可以访问导出的软件包符号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{}

这是个坏主意。你不想为了舒适而创建整个软件包的di。这不仅仅是为了舒适,而是为了让我能够扩展,为那些需要它们的人提供可选的扩展,而不必向所有人提供thm。对于那些说“你不需要这个”的人,我会告诉他们,如果你有答案,就回答吧。然后建议另一种方法。很多时候,即使作者真的需要一些不同的东西,很多人都从搜索中得到了这个问题,需要的正是这些。有没有一种方法可以在运行时动态加载其他语言?CGO只允许特定的加载。所以在程序开始时(而不是在运行时选择)。这是否回答了您的问题?谢谢,我知道DLL是不受支持的,但如果有任何一个新的方法来伪造像他们一样的东西,我是很热心的。看起来RPC是可行的,动态重新编译对库不起作用。经过一些测试后,RPC似乎无法满足我的需要:(目前看来,使用所有go代码的插件系统是不可能的。一年后:这方面的事情有没有发展?像Milo一样,我正在尝试用纯go创建一个插件系统:-/我知道go 1.5将支持生成动态库,但我不确定它是否支持动态加载。有人知道吗?另请参阅: