node源码详解(四) —— js代码如何调用C++的函数

知识共享许可协议本作品采用知识共享署名 4.0 国际许可协议进行许可。转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource4 
本博客同步在https://cnodejs.org/topic/56ed249356d74f3d3624b3ff 
本博客同步在http://www.cnblogs.com/papertree/p/5285705.html


  上面讲到node调用Script::Compile()和Script::Run()解析执行app.js,并把io操作和callback保存到default_loop_struct,那么app.js里面js代码如何调用C++的函数呢?

  在4.2节进行解释,先在4.1节来点知识预热。

4.1 V8运行js代码的基础知识 —— V8的上下文

  来看看google V8开发者文档的一点介绍:(地址:https://developers.google.com/v8/get_started)

  • context is an execution environment that allows separate, unrelated, JavaScript code to run in a single instance of V8. You must explicitly specify the context in which you want any JavaScript code to be run.

  大概意思就是context(上下文)是用来执行javascript代码的运行环境,而且运行javascript代码的时候必须指定一个context。

  从文档里面摘了一段hello world代码:

int main(int argc, char* argv[]) {// Initialize V8.
  V8::InitializeICU();V8::InitializeExternalStartupData(argv[0]);Platform* platform = platform::CreateDefaultPlatform();V8::InitializePlatform(platform);V8::Initialize();// Create a new Isolate and make it the current one.
  ArrayBufferAllocator allocator;Isolate::CreateParams create_params;create_params.array_buffer_allocator = &allocator;Isolate* isolate = Isolate::New(create_params);{Isolate::Scope isolate_scope(isolate);// Create a stack-allocated handle scope.
    HandleScope handle_scope(isolate);// Create a new context.Local<Context> context = Context::New(isolate);// Enter the context for compiling and running the hello world script.
    Context::Scope context_scope(context);// Create a string containing the JavaScript source code.Local<String> source =String::NewFromUtf8(isolate, "'Hello' + ', World!'",NewStringType::kNormal).ToLocalChecked();// Compile the source code.Local<Script> script = Script::Compile(context, source).ToLocalChecked();// Run the script to get the result.Local<Value> result = script->Run(context).ToLocalChecked();// Convert the result to an UTF8 string and print it.
    String::Utf8Value utf8(result);printf("%s\n", *utf8);}// Dispose the isolate and tear down V8.isolate->Dispose();V8::Dispose();V8::ShutdownPlatform();delete platform;return 0;
}

 

  你可能会发现,上面说了script->Run(context) 一定要指定一个context。那么看回3.1.2 中的图3-1-3,node.cc里面的script->Run()并没有context参数。

  跳到v8的源码,deps/v8/src/api.cc,就会发现这实际上是两个重载函数,无参Script::Run()会先从Script对象取得当前的context,再调用Script::Run(Local<Context> context)。

   

图4-1-1

 


 

4.2 理解js代码如何调用C++函数 —— 运行时的上下文

  看个例子:

  左边为node 原生lib模块网络socket操作部分的文件 —— net.js,我们平时使用server.listen()时,最终调用到net.js里面,先通过new TCP()创建一个handle对象,再调用handle.listen()。而这个TCP和listen,均来自左边tcp_wrap.cc文件。

  也就是说,通过net.js里面的handle.listen()调用了tcp_wrap.cc里面的TCPWrap::Listen()函数,并且传给handle.listen()的 js参数—— backlog,被包装到了C++的 FunctionCallbackInfo<Value>类对象args。

图4-2-1 

 

  如果你第一感觉是js代码调用C++代码无法理解,那么一定是受到“语法”的干扰。

  确实,从静态的角度来看,js和C++是两种语言,语法不互通,直接在js代码调用C++函数那是不可能的。

  那么,从动态的角度(运行时)来看呢?别忘了,任何编程语言最终运行起来都不过是进程空间里的二进制代码和数据。

 

   

图 4-2-2

4.2.1 从js代码到context

  4.1 中已经讲了,Script::Compile()和Script::Run() 的时候必须为 js代码指定一个运行环境(context)。那么 js代码和context的关联是很自然的。

4.2.2 设置C++函数到context

  那么,上图蓝色标号1-5这几个步骤,即在C++代码层面,把C++函数设置到context的细节和相应的V8 接口是什么呢?

 


4.3 node的js模块调用C++模块的细节

  在node里面,在C++代码里面提供给运行时javascript代码使用的无非就是这几种:

  1. 一个对象(比如process),对象上设置属性(比如process.versions)、或者方法(比如process._kill)

  2. 函数对象(比如TCP),设置原型方法(比如TCP.prototype.listen)

4.3.1  process对象 —— V8的Object类

  在3.2中讲到,main函数启动后会加载执行src/node.js文件,并且把process对象传给node.js文件,在里面设置process.nextTick()等方法。

  那么来看看 C++如何创建一个给js使用的对象。

4.3.1.1 类型

  回去3.1.2节看一下“图3-1-3”。在LoadEnvironment() 里面执行 f->Call()调用node.js里的匿名函数时,传过去的process对象是通过env->process_object()获取的。

  env->process_object()的实现如下: 

 图 4-3-1

  这里是个宏,展开就是

inline v8::Local<v8::Object> Environment::process_object() const {return StrongPersistentToLocal(process_object_);
}

 

  那么上面标红的process_object_ 成员,定义如下:

图 4-3-2

  这里也是一个宏,展开就是

class Environment {v8::Persistent<v8::Object> process_object_;
}

  那么这里可以看到,C++里面提供给js代码的对象,就是一个v8::Object类型的对象。

4.3.1.2 设置属性或方法

  那么,v8::Object类型的对象如何在C++里面设置属性呢?

图4-3-3

  这里可以看到,v8::Object类提供了Set()方法,来让你设置供js访问的属性或方法。

 

4.3.2 TCP类 —— v8的FunctionTemplate类

  那么第二种类型,就是设置prototype方法。在js里面,没有真正的类的概念,而是通过给函数对象TCP的prototype属性设置方法,使用的时候通过new TCP()去创建实例。

  那么,v8如何设置原型方法?

4.3.2.1 设置原型方法

图4-3-4

  这里可以看到,通过创建一个v8::FunctionTemplate类型的对象 t,通过 t->PrototypeTemplate() 去获取函数对象的prototype,并进一步调用Set()去设置prototype上的方法。

  最后再通过 t->GetFunction() 去获取一个该函数模版的方法。

  

注:关于 js文件process.binding('tcp_wrap')引入TCP函数对象的机制,在下一篇博客讲。

 

转载于:https://www.cnblogs.com/papertree/p/5285705.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EasyConnect安装使用教程

easyconnect电脑版是一款为企业提供的移动信息化办公软件&#xff0c;这款软件可以让公司经常出差的人员能在公司范围外使用公司的内网系统和相关应用。软件支持移动和pc平台&#xff0c;不管是在电脑上还是手机上使用都非常方便&#xff0c;easyconnect电脑版便捷性和安全性使…

xp如何快速锁定计算机,Window XP中快速锁定计算机两法

在Windows XP时工作时&#xff0c;我们经常要锁定计算机&#xff0c;当计算机被锁定后&#xff0c;只有重新登录才能够使用计算机&#xff0c;从而保证了计算机的安全。但是&#xff0c;一般情况下我们需要锁定计算机操作时&#xff0c;都是按下CTRLALTDEL(或者为Delete)键&…

辅助判卷程序项目的扩展--自动出题

既完成了主模块---计算题目的设计后&#xff0c;我就开始了自动出题程序的设计&#xff0c;这个程序的思路比较简单&#xff0c;并不是很完美 下面是程序截图和生成的算式 题目中最多包含一对括号&#xff0c;此程序唯一的遗憾就是有时候计算结果会很大例如7736/4这样的结果 下…

H5工程师跨页面取值的几种方法

业务场景:作为H5工程师,经常需要到另一个页面去拿变量值,遇到好多次啦,这里总结一下,同等不同的页面一般不可以使用id或者类选择器定位取值,比如A页面有个id="demo",你从B页面取值,取不到,我记得上次在jsp中取到过一次,应该是和属性相关的,在js中完全行不通…

计算机的发展阶段及特点与未来发展,计算机的发展历史及未来

芯片快将近10亿倍。光子计算机光子计算机即全光数字计算机&#xff0c;以光子代替电子, 光互连代替导线互连&#xff0c;光硬件代替计算机中的电子硬件&#xff0c;光运算代替电运算。光的高速&#xff0c;天然地决定了光计算机有超高速运算速度&#xff1b;与只能在低温下工作…

akka2.5_播放2.0:Akka,Rest,Json和依赖项

akka2.5在过去的几个月中&#xff0c;我越来越多地涉足scala。 Scala与“ Play框架”一起为您提供了一个非常有效且快速的开发环境&#xff08;即&#xff0c;您掌握了Scala语言的特质之后&#xff09;。 Play框架背后的家伙一直在努力开发新版本的Play 2.0。 在Play 2.0中&…

第三周学习进度条

第三周 所花时间(包括上课) 26 代码量(行) 253 博客量(篇) 2 了解到的知识点 第一次团队合作&#xff0c;发现要学习的东西还很多&#xff0c;合作伙伴之间还是需要磨合的&#xff0c;两个人之间还是需要沟通的&#xff0c;果然容易打起来。。。 知识上进一步了解了栈…

javaScript实现E-mail 验证

下面的函数检查输入的数据是否符合电子邮件地址的基本语法。 意思就是说&#xff0c;输入的数据必须包含 符号和点号 (.)。同时&#xff0c; 不可以是邮件地址的首字符&#xff0c;并且 之后需有至少一个点号&#xff1a; function validateForm(){var xdocument.forms["…

计算机硬件知识竞赛题库,电脑知识竞赛题库.pdf

1&#xff0e;在下列系统中&#xff0c; ( )是实时系统。A. 计算机激光照排系统 B.航空定票系统 C&#xff0e;办公自动化系统 D.计算机辅助设计系统答案&#xff1a; B2&#xff0e;操作系统是一种 ( ) 。A. 应用软件 B &#xff0e;系统软件 C&#xff0e;通用软件 D &#x…

代码挑战“ Vrolijke Framboos”事后验尸

星期二&#xff0c;我们在JDriven举行了第二次“ Vrolijke Framboos”&#xff08;快乐树莓的荷兰语&#xff09;Java代码挑战赛 &#xff0c;这是爆炸性的&#xff01; 今年的挑战是创建一个REST服务客户端&#xff0c;该客户端将与服务器一起玩猜数字游戏。 设置会话后&#…

电子门锁没电的解决办法

导读:今天对象回家,输入电子门锁密码怎么也打不开,指示灯也不亮,前段时间也时不时的能按,我就预感到电池没电了,那么我是如何进入家门的呢? 一般这种电子门锁可以输入密码,也可以使用机械钥匙。说实话,这钥匙在哪我压根没见过,租的房子,房东都不知道,只能输入密码才…

oracle学习笔记系列------oracle 基本操作之表的增删改查

--创建一个表 CREATE TABLE employee_souvc(id NUMBER(4),name VARCHAR2(20),gender CHAR(1),birth DATE,salary NUMBER(6,2),job VARCHAR2(30),deptno NUMBER(2) ); --DESC table_name:查看表结构,看到表的列的名字&#xff0c;以及对应的类型&#xff0c;长度等 DESC employe…

【前端笔试题】文本居中的几种小技巧

前端面试或者开发总会遇到是文本居中的情况及场景,这里一起总结一下。便于查找和使用。 目录 方法一 方法二 方法三 方法四 方法一 自动外边距 div #container{margin-left:auto;margin-right:auto;width:168px;} 方法二 使用text-align body{text-align:center;}

计算机专业常用图论,同等学力申硕计算机专业--数学公式集合(新增学习笔记)...

组合数学部分&#xff1a;基础公式&#xff1a;定义:从n个不同的元素中, 取r个并按次序排列, 称为从n中取r个的一个排列, 全部这样的排列数记为P(n, r).定义: 从n个不同的元素中, 取r个但是不考虑次序时候, 称为从n中取r个的一个组合, 全部这样的组合总数记为C(n, r).定义: 从n…

使用Ubuntu22+Minikube快速搭建K8S开发环境

安装Vmware 这一步&#xff0c;可以参考我的如下课程。 安装Ubuntu22 下载ISO镜像 这里我推荐从清华镜像源下载&#xff0c;速度会快非常多。 下载地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/22.04.3/ 如果你报名了我的这门视频课程&#xf…

linux内核分析——扒开系统调用的三层皮(上)

20135125陈智威 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统调用&#xff1a;库函数封装了系统调用&#xff0c;通过库函数和系统调用打交道 用户态&#xff1a;低级别执行状态&#xff0c;代码的掌控范围会受到限…

前端常见浏览器兼容性问题及解决办法

不同浏览器的内核也不尽相同&#xff0c;所以各个浏览器对网页的解析存在一定的差异。 1.不同浏览器的标签默认的外补丁和内补丁不同 *{ margin:0; padding:0; } 2. 块属性标签float后&#xff0c;又有横行的margin情况下&#xff0c;在IE6显示margin比设置的大 style{ disp…

unchecked异常_为什么要在Java中使用Unchecked异常而不是Checked异常

unchecked异常关于检查与未检查的异常的争论可以追溯到过去。 有人说这是Java包含的最佳功能之一。 其他人则说这是他们最大的错误之一[ 1 ]。 辩论似乎结束了。 在这篇文章中&#xff0c;我将尝试包含涉及该主题的文章和书籍的链接。 我不是专家&#xff0c;但是我会尽力向您解…

微型计算机系统中的内部寄存,微机原理与接口技术习题集汇总.doc

微机原理与接口技术习题集汇总.doc (50页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;29.9 积分&#xfeff;.word格式,第二章 微机基本组成及工作原理1.1微型机的基本结构一、单项选择题1&#xf…

10个对Web开发者最有用的Python包

Python最近成为了开发人员最喜欢的语言之一。无论你是专业的&#xff0c;业余的&#xff0c;还是一个初学者&#xff0c;你都可以从Python语言及其程序包中受益。Python已经被证明是当今最具活力的面向对象的编程语言之一。这就是为什么即使是世界顶级公司也广泛使用这种语言的…