位置: 编程技术 - 正文

用C/C++来实现 Node.js 的模块(一)(c++ not1)

编辑:rootadmin

推荐整理分享用C/C++来实现 Node.js 的模块(一)(c++ not1),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:c++ not,c++ nops,c++ nop,c++ nops,c++ node,c++ node,c++ nops,c++ node,内容如对您有帮助,希望把文章链接给更多的朋友!

 N久之前的一个坑——用 Node.js 来重构 NBUT 的 Online Judge,包括评测端也得重构一遍。(至于什么时候完成大家就不要关心了,(/?Д′)/~ ??

  总之我们现在要做的其实简而言之就是——用C/C++来实现 Node.js 的模块。

准备工作

  工欲善其事,必先~~耍流氓~~利其器。

node-gyp

  首先你需要一个 node-gyp 模块。

  在任意角落,执行:

  在进行一系列的 blahblah 之后,你就安装好了。

Python

  然后你需要有个 python 环境。

  自己去官网搞一个来。

注意: 根据 node-gyp 的GitHub显示,请务必保证你的 python 版本介于 2.5.0 和 3.0.0 之间。 编译环境

  嘛嘛,我就偷懒点不细写了,还请自己移步到 node-gyp 去看编译器的需求。并且倒腾好。

入门

  我就拿官网的入门 Hello World说事儿了。

Hello World

  请准备一个 C++ 文件,比如就叫 ~~sb.cc~~ hello.cc。

  然后我们一步步来,先往里面搞出头文件和定义好命名空间:

主要函数

  接下去我们写一个函数,其返回值是 Handle<Value>。

  然后我来粗粗解析一下这些东西:

Handle<Value>

  做人要有节操,我事先申明我是从这里(@fool)参考的。

V8 里使用 Handle 类型来托管 JavaScript 对象,与 C++ 的 std::sharedpointer 类似,Handle 类型间的赋值均是直接传递对象引用,但不同的是,V8 使用自己的 GC 来管理对象生命周期,而不是智能指针常用的引用计数。

JavaScript 类型在 C++ 中均有对应的自定义类型,如 String 、 Integer 、 Object 、 Date 、 Array 等,严格遵守在 JavaScript 中的继承关系。 C++ 中使用这些类型时,必须使用 Handle 托管,以使用 GC 来管理它们的生命周期,而不使用原生栈和堆。   而这个所谓的 Value ,从 V8 引擎的头文件 v8.h 中的各种继承关系中可以看出来,其实就是 JavaScript 中各种对象的基类。

  在了解了这件事之后,我们大致能明白上面那段函数的申明的意思就是说,我们写一个 Hello 函数,其返回的是一个不定类型的值。

注意: 我们只能返回特定的类型,即在 Handle 托管下的 String 啊 Integer 啊等等等等。 Arguments

  这个就是传入这个函数的参数了。我们都知道在 Node.js 中,参数个数是乱来的。而这些参数传进去到 C++ 中的时候,就转变成了这个 Arguments 类型的对象了。

  具体的用法我们在后面再说,在这里只需要明白这个是个什么东西就好。(为毛要卖关子?因为 Node.js 官方文档中的例子就是分开来讲的,我现在只是讲第一个 Hello World 的例子而已( ´&#;&#;&#;)σ

添砖加瓦

  接下去我们就开始添砖加瓦了。就最简单的两句话:

  这两句话是什么意思呢?大致的意思就是返回一个 Node.js 中的字符串 "world"。

HandleScope

  同参考自这里。

Handle 的生命周期和 C++ 智能指针不同,并不是在 C++ 语义的 scope 内生存(即{} 包围的部分),而需要通过 HandleScope 手动指定。HandleScope 只能分配在栈上,HandleScope 对象声明后,其后建立的 Handle 都由 HandleScope 来管理生命周期,HandleScope 对象析构后,其管理的 Handle 将由 GC 判断是否回收。   所以呢,我们得在需要管理他的生命周期的时候申明这个 Scope 。好的,那么为什么我们的代码不这么写呢?

  因为当函数返回时,scope 会被析构,其管理的Handle也都将被回收,所以这个 String 就会变得没有意义。

  所以呢 V8 就想出了个神奇的点子——HandleScope::Close(Handle<T> Value) 函数!这个函数的用处就是关闭这个 Scope 并且把里面的参数转交给上一个 Scope 管理,也就是进入这个函数前的 Scope。

  于是就有了我们之前的代码 scope.Close(String::New("world"));。

用C/C++来实现 Node.js 的模块(一)(c++ not1)

String::New

  这个 String 类所对应的就是 Node.js 中原生的字符串类。继承自 Value 类。与此类似,还有:

&#;Array&#;Integer&#;Boolean&#;Object&#;Date&#;Number&#;Function&#;...   这些东西有些是继承自 Value,有些是二次继承。我们这里就不多做研究,自己可以看看 V8 的代码(至少是头文件)研究研究或者看看这个手册。

  而这个 New 呢?这里可以看的。就是新建一个 String 对象。

  至此,这个主要函数我们就解析完毕了。

导出对象

  我们来温习一下,如果是在 Node.js 里面写的话,我们怎么导出函数或者对象什么的呢?

  那么,在 C++ 中我们该如何做到这一步呢?

初始化函数

  首先,我们写个初始化函数:

  这是龟腚!函数名什么的无所谓,但是传入的参数一定是一个 Handle<Object>,代表我们下面将要在这货上导出东西。

  然后,我们就在这里面写上导出的东西了:

  大致的意思就是说,为这个 exports 对象添加一个字段叫 hello,所对应的东西是一个函数,而这个函数就是我们亲爱的 Hello 函数了。

  用伪代码写直白点就是:

  大功告成!

  (大功告成你妹啊!闭嘴( ‘д‘&#;彡☆))Д´)

真·导出

  这才是最后一步,我们最后要申明,这个就是导出的入口,所以我们在代码的末尾加上这一行:NODE_MODULE(hello, init)

  纳了个尼?!这又是什么东西?

  别着急,这个 NODE_MODULE 是一个宏,它的意思呢就是说我们采用 init 这个初始化函数来把要导出的东西导出到 hello 中。那么这个 hello 哪来呢?

  它来自文件名!对,没错,它来自文件名。你并不需要事先申明它,你也不必担心不能用,总之你的这个最终编译好的二进制文件名叫什么,这里的 hello 你就填什么,当然要除去后缀名了。

  详见官方文档。

Note that all Node addons must export an initialization function:

There is no semi-colon after NODE_MODULE as it's not a function (see node.h).

The module_name needs to match the filename of the final binary (minus the .node suffix). 编译 (&#;&#;&#; &#; &#;&#;&#;)

  来吧,让我们一起编译吧!

  我们再新建一个类似于 Makefile 的归档文件吧——binding.gyp。

  并且在里面添加这样的代码:

  为什么这么写呢?可以参考 node-gyp 的官方文档。

configure

  在文件搞好之后,我们要在这个目录下面执行这个命令了:

  如果一切正常的话,应该会生成一个 build 的目录,然后里面有相关文件,也许是 M$ Visual Studio 的 vcxproj 文件等,也许是 Makefile ,视平台而定。

build

  Makefile 也生成好之后,我们就开始构造编译了:$ node-gyp build

  等到一切编译完成,才算是真正的大功告成了!不信你去看看 build/Release 目录,下面是不是有一个 hello.node 文件了?没错,这个就是 C++ 等下要给 Node.js 捡的肥皂!

搞基吧!Node ?(&#;&#;?&#;)ノ C++

  我们在刚才那个目录下新建一个文件 jianfeizao.js:

  看到没!看到没!出来了出来了!Node.js 和 C++ 搞基的结果!这个 addon.hello() 就是我们之前在 C++ 代码中写的 Handle<Value> Hello(const Arguments& args) 了,我们现在就已经把它返回的值给输出了。

洗洗睡吧,下节更深入

  时间不早了,今天就写到这里了,至此为止大家都能搞出最基础的 Hello world 的 C++ 扩展了吧。下一次写的应该会更深入一点,至于下一次是什么时候,我也不知道啦其实。   (喂喂喂,撸主怎么可以这么不负责!(o&#;&#;&#;)┌┛Σ(&#;´ω`)&#;

用C/C++来实现 Node.js 的模块(二) 温故而知新,可以为湿矣首先请大家记住这个V8的在线手册——

Nodejs异步回调的优雅处理方法 前言Nodejs最大的亮点就在于事件驱动,非阻塞I/O模型,这使得Nodejs具有很强的并发处理能力,非常适合编写网络应用。在Nodejs中大部分的I/O操作几乎都

我用的一些Node.js开发工具、开发包、框架等总结 开发工具1.WebStorm,毫无疑问非他莫属,跨平台,强大的代码提示,支持Nodejs调试,此外还支持vi编辑模式,这点我很喜欢。2.做些小型项目用SublimeText。3

标签: c++ not1

本文链接地址:https://www.jiuchutong.com/biancheng/374290.html 转载请保留说明!

上一篇:小结Node.js中非阻塞IO和事件循环(node.js基本语法)

下一篇:用C/C++来实现 Node.js 的模块(二)(c++ nops)

  • 企业所得税的征收对象是什么
  • 有经营许可无道路运输证罚多少钱
  • 计提增值税如何处理
  • 税务定税按什么标准
  • 车辆购置税完税证明是什么
  • 电子税务局没有发票开具
  • 加计扣除进项税账务处理
  • 长期待摊销费用属于什么类科目
  • 红字发票信息表需要盖章吗
  • 个人交的社保发票怎么开
  • 融资租赁承租方会计账务处理流程
  • 如何降低应用耗电
  • 有支出没有发票应怎么整改
  • 公户转私户的钱几天能到账
  • 生产车间维修费
  • 租个人房子开发票税率是多少
  • 营改增劳务派遣
  • 没有业务来往可以报税吗
  • 一个人有多份工作
  • 房地产预收款如何申报增值税
  • 业务招待费扣除计算举例说明
  • 企业财务负责人和办税人哪个责任大
  • 未分配利润怎么处理
  • 土地增值税怎么预交
  • 年终奖个税公式 2022
  • 审计报告报备流程
  • 教育费附加免征还计提吗
  • 培训机构的收入有哪几方面
  • windows安装程序无法配置在硬件上
  • 损益类科目反映企业在一定期间内利润或亏损,可以分为
  • 母公司给全资子公司担保需要决议吗
  • 如何在excel中计算两列数值的差
  • php自学
  • PHP:pg_fetch_all()的用法_PostgreSQL函数
  • 同一控制下的控股合并中,合并方个别财务报表
  • 未分配收益怎么取出
  • 转销盘盈会计分录
  • 技术转让费会计处理
  • 所有非批扣和所有批扣是什么意思
  • 开票一定要对公户嘛
  • 奥勒松又叫什么
  • 前端的基础知识
  • thinkphp登录验证
  • SSD目标检测算法
  • 深度学习之快速实现数据集增强的方法
  • 进口增值税科目
  • 小餐饮需要交什么税
  • 企业对外担保代偿能否税前扣除 税务局
  • 招待费的进项税必须认证后转出吗
  • 企业应收票据贴现,应按实际收到的金额计入
  • mongodb基础知识
  • 代开运输发票是否会引起双重征税?
  • 购房补贴退契税3个月没到账
  • sql服务器无法启动的解决
  • 个体户经营所得税率表
  • 固定资产折旧提完了继续使用
  • 固定资产汽车折旧年限是多少年
  • 租赁存在的原因有哪些
  • 国有企业取得的土地建设职工住宅
  • 核销应收帐款分录
  • 代金券消费怎么入账
  • 结转收入会计分录怎么做
  • 存出保证金的账务处理
  • 个人购买办公用品 可以证明是单位吗
  • xp 跳过 chkdsk
  • javascript到c
  • 欢迎使用来电提醒业务是什么意思
  • linux tcptraceroute
  • javascript例子
  • 实现每个星期的计划英语
  • unity之血瓶金币的生成
  • [置顶]马粥街残酷史
  • 基于python的推荐系统
  • JavaScript中Number.MIN_VALUE属性的使用示例
  • javascript学习指南
  • unity camera fov
  • 安卓自定义app
  • 严守纪律守规矩
  • 服务类发票 如何入账
  • 今年烟草税多少钱
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设