golang plugin的依赖问题

此文中涉及的plugin运行环境为mac 10.14,go版本为1.11

主要是想讨论一下插件依赖的第三方库的问题.

例子是在https://github.com/vladimirvivien/go-plugin-example一文基础之上.

简单插件

1.主程序

package main

import (
"fmt"
"os"
"plugin"
) type Greeter interface {
Greet()
} func main() {
// load module
// 1. open the so file to load the symbols
plug, err := plugin.Open("./eng/eng.so")
if err != nil {
fmt.Println(err)
os.Exit(1)
} // 2. look up a symbol (an exported function or variable)
// in this case, variable Greeter
symGreeter, err := plug.Lookup("Greeter")
if err != nil {
fmt.Println(err)
os.Exit(1)
} // 3. Assert that loaded symbol is of a desired type
// in this case interface type Greeter (defined above)
var greeter Greeter
greeter, ok := symGreeter.(Greeter)
if !ok {
fmt.Println("unexpected type from module symbol")
os.Exit(1)
} // 4. use the module
greeter.Greet() }

2. plugin代码

package main

import "fmt"

type greeting string

func (g greeting) Greet() {
fmt.Println("Hello Universe")
} // exported
var Greeter greeting

3. plugin编译方法

go build -buildmode=plugin -o eng/eng.so eng/greeter.go

4. 运行结果

go run main.go
Hello Universe

插件与主程序依赖第三方库的问题

如果主程序和插件都依赖第三方库会有什么问题呢?他们是共享一份代码?还是完全独立的copy呢?

这就类似于c语言动态链接库的依赖,但是应该又不一样. 以实验结果说话吧.

1. 同时依赖的第三方库

package anotherlib
var ShareVariable =7

2. 运行结果

和平时常见的动态库行为一致,也就是说主程序和插件共享了一份运行代码,也共享了一份运行变量.

引入了vendor的问题

实际项目中,可能代码都会使用vendor来管理自己的第三方依赖库.

这时候就会出现不一致的情况.也就是说因为主程序使用了vendor或者插件使用了vendor,

那么这时候go runtime就会认为插件和主程序用的不是同一个第三方依赖库,这时候就会出现和预期不一致的情况.

完整的代码

我已经把代码放在github,刚兴趣可以下载运行,

main.go

package main

import (
"fmt"
"os"
"plugin"
"github.com/nkbai/blog/goplugin/anotherlib"
) type Greeter interface {
Greet()
GetShareVariable() int
} func main() {
// load module
// 1. open the so file to load the symbols
plug, err := plugin.Open("./eng/eng.so")
if err != nil {
fmt.Println(err)
os.Exit(1)
} // 2. look up a symbol (an exported function or variable)
// in this case, variable Greeter
symGreeter, err := plug.Lookup("Greeter")
if err != nil {
fmt.Println(err)
os.Exit(1)
} // 3. Assert that loaded symbol is of a desired type
// in this case interface type Greeter (defined above)
var greeter Greeter
greeter, ok := symGreeter.(Greeter)
if !ok {
fmt.Println("unexpected type from module symbol")
os.Exit(1)
} // 4. use the module
greeter.Greet() fmt.Println("anotherlib in main")
fmt.Println(anotherlib.ShareVariable)
fmt.Printf("plugin anotherlib =%d\n",greeter.GetShareVariable())
fmt.Println("change anotherlib's variable")
anotherlib.ShareVariable=5
fmt.Printf("main share=%d,plugin share=%d\n",anotherlib.ShareVariable,greeter.GetShareVariable())
//可以看到输出都是5 //下面这种情况将会出现不一致的情况
testpluginvendor()
} func testpluginvendor(){
// load module
// 1. open the so file to load the symbols
plug, err := plugin.Open("pluginwithvendor/eng.so")
if err != nil {
fmt.Println(err)
os.Exit(1)
} // 2. look up a symbol (an exported function or variable)
// in this case, variable Greeter
symGreeter, err := plug.Lookup("Greeter")
if err != nil {
fmt.Println(err)
os.Exit(1)
} // 3. Assert that loaded symbol is of a desired type
// in this case interface type Greeter (defined above)
var greeter Greeter
greeter, ok := symGreeter.(Greeter)
if !ok {
fmt.Println("unexpected type from module symbol")
os.Exit(1)
} // 4. use the module
greeter.Greet()
fmt.Println("call plugin withvendor")
fmt.Println("anotherlib in main")
fmt.Println(anotherlib.ShareVariable)
fmt.Printf("plugin anotherlib =%d\n",greeter.GetShareVariable())
fmt.Println("change anotherlib's variable")
anotherlib.ShareVariable=5
fmt.Printf("main share=%d,plugin share=%d\n",anotherlib.ShareVariable,greeter.GetShareVariable())
//可以看到输出并不一致
}

plugin eng.go

package main

import "fmt"
import "github.com/nkbai/blog/goplugin/anotherlib" type greeting string func (g greeting) Greet() {
fmt.Println("Hello Universe")
}
func (g greeting) GetShareVariable() int{
return anotherlib.ShareVariable
}
// exported
var Greeter greeting

第三方依赖库 anotherlib.go

package anotherlib
var ShareVariable =7

golang plugin的依赖问题的更多相关文章

  1. Sublime+Golang Plugin

    很喜欢在Sublime开发Golang程序,主要是要一个Sublime Golang Plugin, 可以给代码autocomplement.相当的棒! 1.安装Sublime https://www ...

  2. 使用Maven Assembly plugin将依赖打包进jar

    一个Eclipse的工程,在pom中配置了若干依赖,需要将pom中所有的依赖全部打包进一个jar包中,可以选择的方案有maven-assembly-plugin和fatjar.以前采用fatjar进行 ...

  3. Golang modules包依赖管理工具

    初始化 执行go mod  init module-name,其中module-name为包名字,执行完后会生成go.mod文件,如下 module module-name go 1.13 包管理 使 ...

  4. install golang plugin in webstrom

    https://github.com/go-lang-plugin-org/go-lang-idea-plugin/wiki/Documentation

  5. Golang 无法下载依赖 golang.org (GoLand解决方法)

    如下图所示将Proxy设置为:https://goproxy.io/

  6. 解决vscode中golang插件依赖安装失败问题

    vscode中安装ms-vscode.go插件后可以开启对go语言的支持,ms-vscode.go插件需要依赖一些工具,安装完成后提示 gocode go-outline go-symbols gur ...

  7. maven工程打包成runnable的jar包,拷贝资源和依赖jar包

    eclipse下新建maven工程,生成runnable的jar包.之前一直是手动拷贝依赖的jar包和资源文件,烦得要死.上网可劲查了一下.解决方案如下. 在pom的配置文件中做如下配置: <b ...

  8. [golang学习] 在idea中code & debug

    [已废弃]不需要看 idea 虽然审美倒退了n年. 不过功能还是相当好用的. idea 的go插件堪称最好的go ide. 1. 语法高亮支持 2. 智能提示 3. 跳转定义(反跳转回来) 4. 集成 ...

  9. 基于Maven管理的Mapreduce程序下载依赖包到LIB目录

    1.Mapreduce程序需要打包作为作业提交到Hadoop集群环境运行,但是程序中有相关的依赖包,如果没有一起打包,会出现xxxxClass Not Found . 2.在pom.xml文件< ...

随机推荐

  1. 如何优化Java垃圾回收-zz

    为什么需要优化GC 或者说的更确切一些,对于基于Java的服务,是否有必要优化GC?应该说,对于所有的基于Java的服务,并不总是需要进行GC优化,但前提是所运行的基于Java的系统,包含了如下参数或 ...

  2. 由python的math.log想到的问题

    result = math.log(243,3) print(result) 输出5.0 print("%f"%result) 还是输出5.0 看出问题了吗?对,没错.int(5. ...

  3. logger 的使用一 小结

    方式一 依赖: <!-- log start --> <dependency> <groupId>log4j</groupId> <artifac ...

  4. 使用打印方法时,要先引用命名空间: Using System.Drawing.Pringing

    使用打印方法时,要先引用命名空间: Using System.Drawing.Pringing PrintDocument类的重要属性和方法:属性:DocumentName  设置打印文档时要显示的文 ...

  5. sass的类型判定

    由于sass的作者是rubyer,因此它的类型与JS有点不一样,但一样可以类推. @charset "utf-8";//必须设置了这个才能编译有中文的注释 $gray: #333; ...

  6. EL 和 JSTL

    EL 什么是EL表达式 EL(Express Lanuage) 表达式可以嵌入在jsp页面内部 减少jsp脚本的编写 EL出现的目的是要替代jsp页面中脚本的编写 作用区间 EL最主要的作用是获取四大 ...

  7. 话说C# 6.0之后

    最想看到的:1. 加入脚本语言支持,可以解释运行,作为程序的二次开发语言(类似于vba,python).2. 可以自定义运算符,为了安全起见,自定义运算符应该特别予以说明(类似于数学表达式,多样式的运 ...

  8. Information Retrieval II

    [Information Retrieval II] 搜索引擎分类: 1.目录式搜索引擎. 2.全文搜索引擎. 3.元搜索引擎(Meta-Search Engine). 搜索引擎的4个阶段:下载(cr ...

  9. 回答了这四个问题,你就可以打造最佳App首页

    如果把手机APP比作人的话,首页就是脸面了.首页是一款产品的大门,好的开头就是成功的一半. 调查表示,26%的手机APP的平均使用次数只有一次.对首次使用产品的用户而言,首页的好坏关乎到用户对该产品的 ...

  10. android 播放视频时切换全屏隐藏状态栏

    1. Demo: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...