Nodejs如何与C++对接的

Nodejs中,进程是一个全局变量,可以在Nodejs的运行过程中,不需要定义的直接使用,类似于前端中的window对象,占据着一个无比重要的位置,基本上,按照我当前的理解,如果没有process对象,那么Nodejs就不是Nodejs了,也就变得和JS完全相同了。

写在前面

其实这里并不是要全面的对process对象进行说明,只是在学习关于Buffer对象和fs模块时,看到了process的相关的东西,所以就顺便先了解一下相关的东西了。

问题来源

在之前的buffer.js和在之后的fs.js中,都出现了process以下的用法:


//buffer.js
var buffer = process.binding('buffer');
var smalloc = process.binding('smalloc');

//fs.js
var binding = process.binding('fs');
var constants = process.binding('constants');


那么关于,process.binding方法,这又是完成了什么功能呢?

process对象是一个全局变量,是由C++实现的,在Nodejs运行时,被加载初始化的,关于process可以直接查找node.cc文件(路径:node-master\srcgithub地址)查找到对应的C++实现代码,对于C++的代码,不做涉及,现在只看一下,在C++代码中,给process对象,添加了哪些属性或者方法,这个可以在node.cc文件的底部看到:


NODE_SET_METHOD(env->process_object(), "_rawDebug", RawDebug);
NODE_SET_METHOD(process,
                  "_startProfilerIdleNotifier",
                  StartProfilerIdleNotifier);
  NODE_SET_METHOD(process,
                  "_stopProfilerIdleNotifier",
                  StopProfilerIdleNotifier);
  NODE_SET_METHOD(process, "_getActiveRequests", GetActiveRequests);
  NODE_SET_METHOD(process, "_getActiveHandles", GetActiveHandles);
  NODE_SET_METHOD(process, "reallyExit", Exit);
  NODE_SET_METHOD(process, "abort", Abort);
  NODE_SET_METHOD(process, "chdir", Chdir);
  NODE_SET_METHOD(process, "cwd", Cwd);

  NODE_SET_METHOD(process, "umask", Umask);

#if defined(__POSIX__) && !defined(__ANDROID__)
  NODE_SET_METHOD(process, "getuid", GetUid);
  NODE_SET_METHOD(process, "setuid", SetUid);

  NODE_SET_METHOD(process, "setgid", SetGid);
  NODE_SET_METHOD(process, "getgid", GetGid);

  NODE_SET_METHOD(process, "getgroups", GetGroups);
  NODE_SET_METHOD(process, "setgroups", SetGroups);
  NODE_SET_METHOD(process, "initgroups", InitGroups);
#endif  // __POSIX__ && !defined(__ANDROID__)

  NODE_SET_METHOD(process, "_kill", Kill);

  NODE_SET_METHOD(process, "_debugProcess", DebugProcess);
  NODE_SET_METHOD(process, "_debugPause", DebugPause);
  NODE_SET_METHOD(process, "_debugEnd", DebugEnd);

  NODE_SET_METHOD(process, "hrtime", Hrtime);

  NODE_SET_METHOD(process, "dlopen", DLOpen);

  NODE_SET_METHOD(process, "uptime", Uptime);
  NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);

  NODE_SET_METHOD(process, "binding", Binding);
  NODE_SET_METHOD(process, "_linkedBinding", LinkedBinding);

  NODE_SET_METHOD(process, "_setupNextTick", SetupNextTick);
  NODE_SET_METHOD(process, "_setupDomainUse", SetupDomainUse);


然后,现在去Nodejs中,确认一下,process具体支持了哪些属性和方法呢,既然最近正好看到文件系统模块,那么就直接把对应的属性直接输出到一个txt文档中即可,所以可以编写nodejs代码如下:


var fs = require("fs"),
    processData = [],
    i;

for(i in process){
    processData.push(i+"\n");
}
fs.writeFile("process.txt",processData.join(""));


这样,当执行node app.js时,就可以在当前目录下,把process的数据,直接输入到process.txt文本中去。其实在process文件中,包含的方法,是多于上述node.cc文件中列出的方法,因为有些方法,并不是在node.cc中直接加载的,而是node.cc调用其他方法,加载到process对象的,这里对这些不多说。

因为process的方法过多,所以这里也就不对这些方法一一列举,有兴趣的可以直接把上述代码copy到一个文件,然后使用nodejs直接编译一下,就可以看到效果了。

这里说了这么多,其实只是在说一些不痛不痒的东西,只是验证了前面的一句话,那就是process对象是通过C++语言实现的,在nodejs中,只是调用即可。

关于binding

作为process的一个属性,binding具体完成了一个怎么样的功能呢,具体的说来,再怎么说,nodejs依然是属于JS的范畴,它本身并没有读取本地文件的功能,所有的高于JS的功能,只是因为nodejs是在服务端运行的,它可以直接和C++交互,通过C++实现文件的读写操作,数据库的读写操作等。

而不管是文件的读写还是数据库的读写等众多JS不能操作的东西,都是通过C++语言实现的,而如果实现C++Nodejs的对接,就是靠的binding方法,它可以把对应C++相关模块进行连接的。

所以,在之前不管是加载process.binding('buffer')process.binding('smalloc')process.binding('fs'),它们都是加载了C++实现的对应的模块而已,比如buffer就是加载的node_buffer.cc模块中的对象,smalloc加载的smalloc.cc的模块,fs加载的node_file.cc模块,对应的方法和数据,都可以通过前面的查看process的相同方法,进行查看。只要把对应的process对象改成需要的对象即可。

总的来说,学习这些东西,对于能更好的理解使用Nodejs是很有好处的,如果可以花一些精力去研究这些C++代码,对于以后写一些自己的插件,完成自己特定的功能,都是很有好处的,只是当前,我还处于学习Nodejs的阶段,所以暂时只要知道一些基本的原理就足够了,更深层次的研究,还是放在以后吧。

总结

这篇文章,在我看来,是属于很重要的一篇,至少对于我个人来说,这个让我对Nodejs的最原理的东西,有了更进一步的认识,对于我以后Nodejs的学习有很好的效果,所以这里就单独写了这篇文章,希望对于在学习Nodejs的你也能有所帮助。

本文地址:http://www.zhangyunling.com/?p=405

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>