go链接库生成调用

go 编译模式

go help buildmode

-buildmode=archive			//把源文件编译成Go语言得静态库文件,如果包名为main会被忽略掉
-buildmode=c-archive		//把你的Go源文件编译成C语言可以使用的静态库,也就是.a文件
-buildmode=c-shared			//把Go源文件编译成C语言可以使用的动态库文件,也就是.so文件或者.dll文件
-buildmode=default			//默认编译方式			
-buildmode=shared			//把Go源文件编译成Go语言可以使用的动态库文件			
-buildmode=exe				//编译成window可执行程序
-buildmode=pie				//编译带上这个参数可以让你的Go程序更安全,没法反编译
-buildmode=plugin			//它将 package main 编译为一个 go 插件,并可在运行时动态加载。只编译main包。

plugin

自从 golang 1.8以后,提供了一个 Plugin 的机制使得 golang能够加载 so 动态链接库文件。

这样可以对外发布动态链接库而不需要把源码共享给对方去进行编译,还可以做到按需加载相应的插件来实现动态开启插件相应的功能。

编写plugin

编写一个 Plugin 基本有以下几步:

1.Plguin 需要有自己的 main package
2.编译的时候,使用 go build -buildmode=plugin file.go 来编译
3.使用 plugin.Open(path string) 来打开.so文件,同一插件只能打开一次,重复打开会报错
4.使用 plugin.LookUp(name string) 来获取插件中对外暴露的方法或者类型
5.使用类型断言,断言后执行相应的方法

插件中定义的 struct 无法暴露出来,可以让主程序和插件程序import公共的 package 来解决
私有方法、变量不会被暴露出来

linux/mac

生成动态链接库

新建plugin文件夹并在该目录下新建xzwPlugin.go

package main

import (
	"fmt"
)

func Call(){
	fmt.Println("plugin.so was called")
}

func CallWithParam(msg string){
	fmt.Println("参数内容为:",msg)
}

func main() {
	fmt.Println("goroute全部退出")
}

编译动态库 ,这个命令不能在windows上运行,go暂时不支持windows上编译动态链接库,只支持静态链接库。
go build --buildmode=plugin xzwPlugin.go

root@ubuntu:/home/xzw/main# go build --buildmode=plugin xzwPlugin.go
root@ubuntu:/home/xzw/main# 
root@ubuntu:/home/xzw/main# ls
xzwPlugin.go  xzwPlugin.so

调用动态链接库

新建xzwLoad.go

package main

import "plugin"


func main() {

	//加载动态库,参数填动态链接库的地址即可
	p, err := plugin.Open("xzwPlugin.so")
	if err != nil {
		panic(err)
	}
	//查找函数
	f, err := p.Lookup("Call")
	if err != nil {
		panic(err)
	}
	//转换类型后调用函数
	f.(func())()


	f2, err := p.Lookup("CallWithParam")
	if err != nil {
		panic(err)
	}

	//带参函数的调用
	f2.(func(string))("hello world,plugin.so")
}

调用动态库:

go run xzwLoad.go

测试

root@ubuntu:/home/xzw/plugin# go build --buildmode=plugin xzwPlugin.go
root@ubuntu:/home/xzw/plugin# ls
xzwLoad.go  xzwPlugin.go  xzwPlugin.so
root@ubuntu:/home/xzw/plugin# go run xzwLoad.go 
plugin.so was called
参数内容为: hello world,plugin.so

C库

注意点:

  1. 必须导入 “C” 包
  2. 必须在可外部调用的函数前加上 【//export 函数名】的注释
  3. 必须是main包,且有main函数,main函数可以什么都不干

生成库

新建plginC文件夹并在该文件夹下新建xzwPlugin.go

package main

import (
	"C"
	"fmt"
)
//export Call
func Call(){
	fmt.Println("plugin.so was called")
}

//export CallWithParam
func CallWithParam(msg string){
	fmt.Println("参数内容为:",msg)
}

func main() {
	fmt.Println("goroute全部退出")
}
生成动态库: go build -buildmode=c-shared -o xzw.so xzwPlugin.go
生成静态库: go build -buildmode=c-archive -o xzw.a xzwPlugin.go
静态库会生成xzw.h和xzw.a 动态库生成xzw.h和xzw.so

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×