欢迎来到我的专题文章:《让C++给node做技术加持》系列。更多内容,持续更新中,欢迎关注。
往期目录:
专题:让C++给node做技术加持(一)环境搭建,项目运行
专题:让C++给node做技术加持(二)-NodeJs调用C++方法
上一章节,我介绍了NodeJs如何与C++进行交互的环境搭建,C++为nodejs提供API,成功实现了双方 的交互。具体细节可移步到第二章节。
NodeJs应用场景
在前端领域,nodejs被应用最广泛的,无非是网站后台。这个时候我们把打包好的.node二进制文件部署到服务器即可。
然后随着nodejs不断发展,桌面端开发也是异常火热。前端圈中以electron为首的桌面应用框架也是琳琅满目。
既然是桌面开发,那肯定有调用操作系统底层的API能力,比如操作数据库,文件读写等,肯定也少了不nodejs支持。
好,前面我们既然能将C++编译好的.node文件给nodejs调用,那是否可以无缝移植到electron项目中来呢?
恩。动手试试就知道了。
首先我们来创建一个electron快速启动的项目,这里就不做演示了,我自己已经创建好了
接下来我们在项目根目录下引入我们通过node-gyp rebuild打包好的.node二进制文件
接下来我们来启动下electron,看效果
//看下面的错误信息,说的好像是版本没匹配对。NODE_MODULE_VERSION 64. This version of Node.js requiresNODE_MODULE_VERSION 76. Please try re-compiling or re-installing
的确是这样的哈,我们的electron中的nodejs使用的v8和普通的nodejs的v8还不太一样,导致正常编译下的.node文件不能被electron使用。
解决问题
接着我们肯定要开始着手解决这个问题了,通过查阅资料,发现在我们在编译C++时针对electron有自己独立的参数。
好了,直接上编译参数了。
node-gyp rebuild --target=8.2.2 --dist-url=https://atom.io/download/electron
--target表示我当前electron的版本为8.2.2 --dist-url表示我们要这个地址下载对应的头文件,这个过程一般很难执行下来。我也是尝试了很多次才搞好的。 我们接下来看下编译过程。
别着急,遇到问题,我们先来看下错误提示。
'MaybeLocal<:string>' to 'v8::Local<:string> &&' for 1st argument
意思就是我们不能像之前这样
Local val = String::NewFromUtf8(isolate,str.c_str()); args.GetReturnValue().Set(val);
直接通过Local去接收返回值了,得替换成MaybeLocal<:string>这种数据类型。
好吧,按照提示来呗。
但是我发现,MaybeLocal这种类型是不能直接返回到NodeJs那边去的。Nodejs那边能接受的类型都是通过Local来定义的。
那怎么样?没办法,只有硬着头皮翻下v8的文档了。我找啊找,找啊找,终于,我找到了这个文档,
好像看到了希望啊。MabelLocal有一个方法ToLocalChecked();可以一试了。
好了,我的编译终于成功了。我们copy下.node文件到electron项目中,接着启动下项目
终于成功调用啦。。。
到这,坑算是填好了。
总结
- 在做项目,或者为项目做技术调研的时候,难免会入坑,查阅资料去把坑填好,也是我们在技术成长中非常重要的一环。
- 这种开发C++本地模块的方式已经不被Nodejs官网推荐了,因为它过度依赖于nodejs版本和electron版本,无法做到一次编写,一次编译。无论是electron还是普通的Nodejs都可以无缝调用。
- 为了解决这些痛点,nodejs已经给了开发者新的开发模块,那就是N-API,它就比较灵活了,后面我们接着说它。
下期,柳暗花明,以N-AP模式基于C++开发nodejs模块的春天要来了。
这里是 畅哥聊技术 《让C++给node做技术加持》专题系列文章,更多内容,持续更新中,欢迎关注。
全文完。