node 调用 golang 开发动态链接库

496 阅读1分钟

背景

在开发electron项目中,很多依赖node 的方式效率比较低,为了提高效率需要Node C++ addon 插件 但是不会c++ 会点golang 于是自己尝试写个demo

技术方案

node 提供node-ffi调用动态链接库,因此golang程序需要最终编译成动态链接库

  • mac 环境下是.dylib文件
  • win环境是.dll文件
  • linux 环境下是.so文件

golang demo

// 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"
// gofun.go
package main

/*#cgo CFLAGS: -I .
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef void (*cb)(char* extra, char* data);
extern void callCb(cb callback, char* extra, char* arg);
*/
import "C"
import "time"

//export helloP
func helloP(arg *C.char, ccb C.cb, extra *C.char) *C.char {
    C.callCb(ccb, extra, C.CString("one"))
    time.Sleep(time.Second)
    C.callCb(ccb, extra, C.CString("two"))
    return C.CString("hello peter:::" + C.GoString(arg))
}
func main() { println("go main func") }

编译成动态链接库

go build -o main.dylib -buildmode=c-shared main.go bridge.go

node部分

var ffi = require('ffi-napi');// 指定路径注册函数
 var libm = ffi.Library('main', {
     'helloP': ['string', ['string', ffi.Function("void", ['string', 'string']), 'string']]
 });
 console.log(libm.helloP("1111",function (a,b){console.log(a,b)},"222"))

到此demo 中能完整的演示 go语言生成动态链接库为node 提供扩展

总结:

go语言取代了c++作为node 扩展的可能性,使得node 的性能有了一定的提升,也降低了开发难度,go语言的上手难度比c++低很多。

不足之处:

1.数据类型转换问题,由于对c不了解  js和go直接的数据类型转换成了一个坑。简易处理方案转换成json字符串调用的时候来解析成对象

2.复杂业务还是无法取代c++,比如带界面的扩展,截图一类的工具开发还是得qt做