nodejs 调用golang
最近在用electron开发一个gui程序, 有一些代码不能暴露出来. 但是JavaScript是解释型语言, 混淆什么的都难以保证代码不被泄露.所以就想写一个原生插件, 暴露接口js调用. js原生插件通常用C++开发, 但是本人不会,去学习的话涉及到的知识太多了,短期内肯定是不行的,不过最近正好在学golang, 就想着能不能用golang去写.
本人目前是php程序猿, c++和golang都是入门水平, 若是代码中有任何不妥,还望大神不吝赐教. 见笑了.
思路
golang 支持编译成c shared library, 也就是系统中常见的.so(windows下是dll)后缀的动态链接库文件. c++可以调用动态链接库,所以基本思路是golang开发主要功能, c++开发插件包装golang函数,实现中转调用
对于类型问题, 为了方便处理, 暴露的golang函数统一接受并返回字符串, 需要传的参数都经过json编码, 返回值亦然. 这里实现了3种调用方式, 同步调用,异步调用和带进度回调的的异步调用.应该能满足大部分需求
参考
golang cgo支持: https://golang.org/cmd/cgo/
实现
不多说直接上代码, 相关说明都写到注释中了
golang部分
// gofun.go
package main
// int a;
// typedef void (*cb)(char* data);
// extern void callCb(cb callback, char* extra, char* arg);
import "C" // C是一个虚包, 上面的注释是c代码, 可以在golang中加 `C.` 前缀访问, 具体参考上面给出的文档
import "time"
//export hello
func hello(arg *C.char) *C.char {
//name := gjson.Get(arg, "name")
//return "hello" + name.String()
return C.CString("hello peter:::" + C.GoString(arg))
} // 通过export注解,把这个函数暴露到动态链接库里面
//export helloP
func helloP(arg *C.char, cb C.cb, extra *C.char) *C.char {
C.callCb(cb, extra, C.CString("one"))
time.Sleep(time.Second)
C.callCb(cb, extra, C.CString("two"))
return C.CString("hello peter:::" + C.GoString(arg))
}
func main() {
println("go main func")
}
// bridge.go
package main
// typedef void (*cb)(char* extra, char* data);
// void callCb(cb callback, char* extra , char* arg) { // c的回调, go将通过这个函数回调c代码
// callback(extra,arg);
// }
import "C"
通过命令go build -o gofun.so -buildmode=c-shared gofun.go bridge.go
编译得到 gofun.so
的链接库文件
通过 go tool cgo -- -exportheader gofun.go
可以得到gofun.h头文件, 可以方便在c++中使用
c++部分
// ext.cpp
#include
#include
#include
#include
#include