背景
在开发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做