当前位置: 首页 > news >正文

生物科技 网站模板下载产品推广网站

生物科技 网站模板下载,产品推广网站,攻击Wordpress网站,电子请帖免费制作appnodejs的很多功能都是通过c或者通过c层调用libuv层实现的,nodejs是如何在js层面调用c的呢?在nodejs里,使用c层的功能主要有两种方式,第一种就是调用全局变量process,Buffer等,第二种就是通过process.bindin…

nodejs的很多功能都是通过c++或者通过c++层调用libuv层实现的,nodejs是如何在js层面调用c++的呢?在nodejs里,使用c++层的功能主要有两种方式,第一种就是调用全局变量process,Buffer等,第二种就是通过process.binding函数。

1 process、buffer等全局变量

首先来看第一个种。在nodejs启动的过程中。在Environment::Start函数中生成了process对象。

// 利用v8新建一个函数auto process_template = FunctionTemplate::New(isolate());// 设置函数名process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate(), "process"));// 利用函数new一个对象auto process_object = process_template->GetFunction()->NewInstance(context()).ToLocalChecked();// 设置env的一个属性,val是process_objectset_process_object(process_object);// 设置process对象的属性SetupProcessObject(this, argc, argv, exec_argc, exec_argv);

以上代码生成了一个process对象并且保存在env里。然后继续执行LoadEnvironment函数。在该函数里会执行bootstrap_node.js。然后执行bootstrap_node.js导出的函数。

 Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(),"bootstrap_node.js");// 执行bootstrap_node.jsLocal<Value> f_value = ExecuteString(env, MainSource(env), script_name);Local<Function> f = Local<Function>::Cast(f_value);// 全局变量,我们访问全局变量的时候都是global的属性Local<Object> global = env->context()->Global()// js层的全局变量,类似浏览器的windowglobal->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);Local<Value> arg = env->process_object();// 执行bootstrap_node.js auto ret = f->Call(env->context(), Null(env->isolate()), 1, &arg);

在bootstrap_node.js的函数里执行setupGlobalVariables函数。

global.process = process;
global.Buffer = NativeModule.require('buffer').Buffer;
process.domain = null;
process._exiting = false;

以上代码设置了几个全局变量,我们访问process的时候就是访问global.process。当v8编译执行bootstrap_node.js的时候,传进来了一个c++的对象process,在js层调用global其实就是调用了c++层的global对象,执行global.process = process的时候,即在c++层面给c++层的global对象新增了一个属性process,他的值是传进来的c++对象process。所以当我们在js层面访问process的时候,v8会在c++层面的global对象里查找process属性,这时候就会找到传进来的c++对象。

2 process.binding

我们看一下我们在js里调用process.binding函数的时候,nodejs都做了什么,首先看一下process.binding的函数是怎么来的,我们知道在nodejs启动的时候新建了一个process对象,并且通过node.cc的SetupProcessObject函数挂载了一系列属性。其中设置了一个属性就是binding

env->SetMethod(process, "binding", Binding);static void Binding(const FunctionCallbackInfo<Value>& args) {Environment* env = Environment::GetCurrent(args);CHECK(args[0]->IsString());Local<String> module = args[0].As<String>();node::Utf8Value module_v(env->isolate(), module);node_module* mod = get_builtin_module(*module_v);Local<Object> exports;if (mod != nullptr) {exports = InitModule(env, mod, module);} else if (!strcmp(*module_v, "constants")) {exports = Object::New(env->isolate());CHECK(exports->SetPrototype(env->context(),Null(env->isolate())).FromJust());DefineConstants(env->isolate(), exports);} else if (!strcmp(*module_v, "natives")) {exports = Object::New(env->isolate());DefineJavaScript(env, exports);} else {return ThrowIfNoSuchModule(env, *module_v);}args.GetReturnValue().Set(exports);
}

在nodejs的启动流程文章中我们分析过binding函数就是在一个内置模块链表中找到对应的模块。然后执行该模块注册的时候,然后返回一个该模块导出的对象。这就是底层的binding函数做的功能,但是我们在调process.binding的时候,并不是直接执行了c++层的binding函数。在bootstrap_node.js中还封装了一层。

const bindingObj = Object.create(null);const getBinding = process.binding;process.binding = function binding(module) {module = String(module);let mod = bindingObj[module];if (typeof mod !== 'object') {mod = bindingObj[module] = getBinding(module);moduleLoadList.push(`Binding ${module}`);}return mod;};

nodejs在这加了一层缓存。下面我们以net.js调用tcp_wrap.cc为例看一下js是如何调用c++的功能的。
当我们执行以下代码时,

const { TCP } = process.binding('tcp_wrap');

v8首先编译js代码,然后在执行时访问process对象,根据1中的分析,这时候就会访问c++层的process对象,然后访问binding属性,即上面绑定的binding函数,该函数会调用C++层的binding函数,返回一个导出的对象exports。接下来我们执行TCP.a或者new TCP的时候,其实就类似于调用一个c++对象的属性或者在c++层面new一个对象一样。这个是由v8进行转换的。即v8在编译解析TCP这个字符串的时候他就会生成访问底层TCP类的代码。

理解js是如何调用c++的,不能把思路停留到静态,要结合v8是如何编译和执行js代码的。比如v8在编译这段代码。

const { TCP } = process.binding('tcp_wrap');
const tcp = new TCP();
tcp.listen();

转化成c++代码或者二进制代码反编译成c++后可能是

HashTable *hash = new HashTable();object * binding(char *str) {if (hash[str]) {return hash[str];}return hash[str] = Binding(str);
}
object * Binding(char *str) {}Object *process = new Object();
Object *Tcp_wrap = new Object();process->binding = binding
Function *TCP = process.binding('tcp_wrap'); => Function *TCP = Tcp_wrap;
object* tcp = new Tcp_wrap();
tcp.listen();

在js里直接调用c++是不可以的,但是js最终是要编译成二进制代码的。在二进制的世界里,js代码和c++代码就可以通信了,因为nodejs定义的那些c++模块和c++变量都是基于v8的架构的,比如定义了一个process对象,或者Binding函数,都是利用了v8的规则和接口。所以在nodejs里,不管是v8内置的js函数,对象,还是nodejs额外提供的那些模块功能,他最后都是由v8去处理的。虽然无法在js里直接调用c++功能,但是可以在js被编译后使用c++功能。而nodejs的实现方案就是实现一个process对象和Binding函数。js里通过process.binding加载一个c++模块的时候,这段js在编译后执行,首先访问js层的process对象,v8知道js的process对象对应是c++的process对象,就像我们在js里定义一个函数或者对象,在编译后v8也知道应该调用的是c++哪些代码,因为我们怎么写脚本以及使用什么功能但是v8提供的,v8在编译执行我们的js脚本的时候,当我会知道需要执行底层哪些代码。所以v8知道需要执行的是c++层的process对象里的Binding函数,通过底层的Binding,就可以使用c++模块的功能了。
当我们使用非v8提供的内置函数时,nodejs里是通过在执行时查找对应模块的形式去实现的,而不是通过在v8的global变量里挂载新的函数。下面是在v8的global里挂载自定义对象的大致流程。

void say(){}
Handle<FunctionTemplate> a_template = FunctionTemplate::New(callbackWhenNewObject);
a_template ->SetClassName(String::New("a_template"));
Handle<ObjectTemplate> a_template _proto = a_template->PrototypeTemplate();
a_template _proto->Set(String::New("say"), FunctionTemplate::New(say));
// 挂载到全局变量,我们在js里就可以直接访问a_template 
global->Set(String::New("a_template "), a_template );

在js里调用

new a_template().say();

总得来说,js是调用c++功能是通过process.binding去实现的,首先是我们在js里调用js层的process.binding,通过v8提供的功能,js层的process.binding在执行的时候是对应c++层的某段代码的,所以js被编译执行时就可以使用c++提供的功能了,因为这时候c++代码和js代码都被编译成二进制代码,通过process.binding就把这两个层面的代码在底层联系起来。

http://www.lbrq.cn/news/2809045.html

相关文章:

  • 学校网站 建设 价格百度网盘资源搜索引擎搜索
  • 用php做网站教程近期国内新闻
  • 南京设计公司前十名无锡网站seo
  • 网站不足重庆seo
  • 温江做网站哪家好搜索引擎排名优化方案
  • r语言做网站软文外链购买平台
  • 政府新闻网站建设方案种子搜索神器在线引擎
  • p2p网贷网站建设今日全国最新疫情通报
  • 做网站可以盈利吗深圳网站优化排名
  • 香港服务器网站销售网站排名
  • ai绘画软件免费百度seo搜索引擎优化厂家
  • 郑州门户网站建设哪家好杭州网站设计
  • 会简单的网站建设怎么自己制作网页
  • 两学一做考试答案网站微信代运营
  • 珠海网站推广价格网络推广服务合同范本
  • 社保网站上怎么做减员视频号视频下载助手app
  • 制作网站赚钱不最简单的网页制作
  • 做导购网站多少钱网址域名ip查询
  • 苏州网站建设制作网站建设方案书模板
  • 手工艺品外贸公司网站建设方案简易的旅游网页制作
  • 邯郸互联网公司seo网站推广实例
  • 洪泽区做网站aso排名优化
  • 做网站哪家公司最好综合查询
  • 天津网站推广宣传重庆网站优化排名推广
  • 嘉兴自助建网站竞价推广和信息流推广
  • 电商类网站建设需要多少钱seo技术培训江门
  • vue做的网站域名汇总百度极速版客服电话
  • WordPress显示403网站优化价格
  • 上海人才网官网招app优化推广
  • 山东最新通知今天山东公司网站推广优化
  • 子类(派生类)使用父类(基类)的成员
  • C++ this 指针
  • c# 和 c++ 怎样结合
  • 直流无刷电机旋转原理
  • Temu美国站大规模扫号封店:虚假本土店遭批量封禁,如何规避?
  • 基于SpringBoot的旅游攻略系统网站【2026最新】