欢迎大家来到我的新专题:《让C++给node做技术加持》系列,技术更新中,欢迎关注。
前沿:看到题目有C++,大家的第一感觉可能我和一样,不想看,原因是我特么一个做前端的,搞什么C++,来不了来不了。。。
莫慌莫慌,我为了这个,学了两天的C++基础,够用啦。
NodeJs问世已有10余载,其异步IO带来高并发让NodeJs在web服务方面稳稳的排在一线。但是node本质是ECMAScript,也就是我们熟知的JS,所以,计算性能也是它天生的不足。
好在Nodejs底层是基于C++开发,而Nodejs官网也给开发者提供了与C++的交互接口。因此我们可以通过C++编写高性能的模块,通过npm模块node-gyp编译成.node的二进制文件供nodeJs调用,主逻辑代码可以更好的被保护
所以用C++编写Node模块优势主要有两点:
- 提高Nodejs执行效率
- 保护源代码
缺点是开发这个代码块门槛相对比较高。
端午三天,小编在家专门研究了这块内容,有所收获,现在把我学习到的分享给大家吧。
下面开始环境搭建。
首先我们在准备好C++的开发环境,windows上建议安装微软的visualstudio 自带C++环境,mac上安装好xCode就行了。安装过程这里就不再赘述了。
其次我们在windows上要安装好python2.7环境。mac上有自带的python2.7环境。
安装好这两环境后,我们需要全局安装将C++编译成.node模块的npm模块 node-gyp
命令:npm install node-gyp -g
完成后我们执行下 node-gyp -v 正常输出版本号,说明安装成功。
环境准备好了后,我们开始大概先跑下官网上的demo吧,然后我来告诉你们,什么叫挫败感。
一起来吧~~
首先,创建一个空目录,
mkdir C++addon && cd C++addon
创建一个我们要编译的C++文件 demo.cc(这里我们可以用.cc或者.cpp都可以),第一步,肯定是抄下官网的demo吧。
第一步完成,接下来我们先来创建一下编译过程中需要的配置文件,binding.gyp,在当前目录下创建这个配置文件,然后写下代码:
{
"targets": [
{
"target_name": "test",//配置编译后的二进制文件名:test.node
"sources": [ "demo.cc" ] //要编译的入口文件
}
]
}
接下来执行命令
node-gyp rebuild
效果如下:
编译成功后,生成一个build文件夹,来看下
接下来,我们通过Node来调用一下它
创建index.js,输入代码
const test = require("./build/Release/test.node");
console.log(test);
console.log(test.hello());
我们来看下效果:
可以看到,我们可以直接通过require一个.node文件,然后返回的是一个hello方法,hello方法调用返回一个world字符串,这个hello方法就是在C++中完成的。
到这里,我们完成了官网上的一个最基础的demo了。
你们以为这样就完了吗?来,和我一起入坑吧。先回到C++代码里面,看这坨代码
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, "world", NewStringType::kNormal).ToLocalChecked());
这里面的字符串world是写死的,一般来说,我们可能想动态传入这个字符串,于是想必大家和我有一样的想法,那就在外面定义一个变量,str 然后赋值就完事了呗。ok,我们按这个方式来试一把。
string str = "畅哥聊技术";
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, str, NewStringType::kNormal).ToLocalChecked());
改成这样,定义了一个str字符串,(C++中要用字符串需要加命名空间using namespace std; ),接下来我们再编译一下。
就这个问题,我也是查了很长时间的资料了,最后解决的办法是传入的str字符串需要调用一个c_str()方法
看最终结果:
入门的第一个坑到这算是完美填上了。
这里是 畅哥聊技术 的 《让C++给node做技术加持》专题系列,更多C++内容持续更新中,欢迎关注。下期带来,如何将C++编译成静态链接库,敬请期待。