SetCallAsFunctionHandler 相当于lua __call

2023-11-08

首先到google开发者网站上下载v8源码,并按照说明进行编译。

v8中,编译和执行的js代码需要依付于一个空间(上下文)。上下文由Context::New创建。

static Persistent<Context> New(
      ExtensionConfiguration* extensions = NULL,
      Handle<ObjectTemplate> global_template = Handle<ObjectTemplate>(),
      Handle<Value> global_object = Handle<Value>());

其中,extensions表示要增加到上下文的额外配置。global_template指定产生上下文内部对象的对象模板。global_object是要重用的上下文内部对象(该对象是以前由Context::New创建出来的上下文内部对象,且其对象模板必须和global_template相同)。要注意的是,如果指定了global_object,则该global_object除了对象标识会被保留外,其它状态全部重置。

上下文就是js中通过对象模拟出来的命名空间:

function namespace_template()
{

    return {};

}

var Namespace = new namespace_template();

with(Namespace)
{

    ...

};

Persistent<Context> context = Context::New(NULL, namespace_template,NULL);//此处的namespace_template仅表示对应关系

Local<Object> Namespace = context->Global();

要使用上下文,需调用:context->Enter();

接下来,编译运行js代码:

Local<Script> script = Script::Compile(String::New("function add(a, b){return a+b;}"));

script->Run();

Script::Compile:在当前上下文中编译js代码。调用Run时,使用的是Script::Compile时的上下文。

Script::New:独立编译js代码。调用Run时,使用的是调用Run时的上下文。

调用JS中的函数:

Local<Value> value_add = Namespace->Get(String::New("add"));

ASSERT(value_add->IsFunction());

Local<Function> fun_add = Local<Function>::Cast(value_add);

Handle<Value> args[2];

args[0] = Uint32::New(1);

args[1] = Uint32::New(2);

Local<Value> result_add = fun_add->Call(Namespace, 2, args);

ASSERT(result_add->IsUint32());

uint32_t ui_result_add = result_add->Uint32Value();

绑定函数(让js调用VC中的代码):

假设VC中的代码为:

int ave(int a, int b, int c){return (a+b+c)/3;}

希望在js中可直接进行如下调用:

var ave_value = ave(10, 20, 3.);

v8无法将C/C++中的函数直接导出,需要一定的转换:

Handle<Value> ave_js(const Arguments& args)

    if(args.Length() < 3) return Undefined();

    int ave_value = ave(args[0]->Int32Value(), args[1]->Int32Value(), args[2]->Int32Value());
    return Int32::New(ave_value);
}

Namespace->Set(String::New("ave"), FunctionTemplate::New(ave_js)->GetFunction());

绑定对象:

假设VC中有一个CRectangle类对象rectangle(在实际使用中要考虑生命周期):

class CRectangle
{

public:

    int w;

    int h;

    int Area() const{return w * h;}

}rectangle;

希望在js中进行如下调用:

rectangle.w = 10;

rectangle.h = 20;

var area = rectangle.Area();

实现:

Handle<Value> Rectangle_Area(const Arguments& args)
{
 Handle<External> field = Handle<External>::Cast(args.Holder()->GetInternalField(0));
 void* raw_rectangle_ptr = field->Value();
 CRectangle* pRectangle = static_cast<CRectangle*>(raw_rectangle_ptr);
 int area_value = pRectangle->Area();

 return Int32::New(area_value);
}

Handle<Value> Rectangle_Getter(Local<String> property, const AccessorInfo& info)
{
 Local<String> sw = String::New("w");
 Local<String> sh = String::New("h");
 Local<String> sarea = String::New("Area");

 Handle<External> field = Handle<External>::Cast(info.Holder()->GetInternalField(0));
 void* raw_rectangle_ptr = field->Value();
 CRectangle* pRectangle = static_cast<CRectangle*>(raw_rectangle_ptr);

 if(property->StrictEquals(sw)) return Int32::New(pRectangle->w);
 if(property->StrictEquals(sh)) return Int32::New(pRectangle->h);
 if(property->StrictEquals(sarea))
 {
  static Local<Function> Area_Fun = FunctionTemplate::New(Rectangle_Area)->GetFunction();
  return Area_Fun;
 }
 return Undefined();
}

Handle<Value> Rectangle_Setter(Local<String> property, Local<Value> value, const AccessorInfo& info)
{
 Local<String> sw = String::New("w");
 Local<String> sh = String::New("h");
 Local<String> sarea = String::New("Area");

 Handle<External> field = Handle<External>::Cast(info.Holder()->GetInternalField(0)) ;
 void* raw_rectangle_ptr = field->Value();
 CRectangle* pRectangle = static_cast<CRectangle*>(raw_rectangle_ptr);

 if(property->StrictEquals(sw)) return Int32::New(pRectangle->w = value->Int32Value());
 if(property->StrictEquals(sh)) return Int32::New(pRectangle->h = value->Int32Value());

 return Undefined();
}

Local<ObjectTemplate> rectangle_template = ObjectTemplate::New();
rectangle_template->SetInternalFieldCount(1); 
rectangle_template->SetNamedPropertyHandler(Rectangle_Getter, Rectangle_Setter);
rectangle_template->Set(String::New("w"), Int32::New(0));//由于设置了属性访问器和设置器,传入的Int32::New(0)不会被使用
rectangle_template->Set(String::New("h"), Int32::New(0));//由于设置了属性访问器和设置器,传入的Int32::New(0)不会被使用
rectangle_template->Set(String::New("Area"), Int32::New(0));//由于设置了属性访问器和设置器,传入的Int32::New(0)不会被使用

Local<Object> rectangle_obj = rectangle_template->NewInstance();

rectangle_obj->SetInternalField(0, External::New(&rectangle));

Namespace->Set(String::New("rectangle"), rectangle_obj);

导出类(js中的构造函数):

希望在js中生成一个Rectangle类:

function Rectangle(w, h)

{

    this.w = w;

    this.h = h;

    this.Area = function(){return this.w * this.h;}

}

进行如下调用:

var rectangle = new Rectangle(10, 20);

var area = rectangle.Area();

rectangle.w = 1;

rectangle.h = 2;

area = rectangle.Area(); 

实现:

Handle<Value> CRectangle_Area(const Arguments& args)
{
 Local< Object > pThis = args.This();
 int w = pThis->Get(String::New("w"))->Int32Value();
 int h = pThis->Get(String::New("h"))->Int32Value();

 return Int32::New(w*h);
}
Handle<Value> Rectangle_InvocationCallback(const Arguments& args)
{
 Local< Object > pThis = args.This() ;
 int w = 0, h = 0;
 if(args.Length() > 0) w = args[0]->Int32Value();
 if(args.Length() > 1) h = args[1]->Int32Value();
 pThis->Set(String::New("w"), Int32::New(w));
 pThis->Set(String::New("h"), Int32::New(h));

 return pThis;
}


 

Local< FunctionTemplate > Rectangle_template = FunctionTemplate::New();

Local<ObjectTemplate> Rectangle_instance_template = Rectangle_template->InstanceTemplate();
Rectangle_instance_template->SetCallAsFunctionHandler(Rectangle_InvocationCallback);
Rectangle_instance_template->Set("w", Number::New(0));
Rectangle_instance_template->Set("h", Number::New(0));
Rectangle_instance_template->Set("Area", FunctionTemplate::New(CRectangle_Area));

Local<Function> Rectangle_function = Rectangle_template->GetFunction();
Local<Object> Rectangle = Rectangle_function->NewInstance();


Namespace
->Set(String::New("Rectangle"), Rectangle);

完整源码请查看本人发布的资源

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SetCallAsFunctionHandler 相当于lua __call 的相关文章

  • 将 jQuery 集成到电子应用程序中

    我正在尝试将 jquery 功能添加到用 Electron 编写的桌面应用程序中 使用电子快速启动存储库 我将下载的 jquery 文件添加到main html像这样的文件 or so 然后在index js我正在文件中添加代码create
  • 是否可以为 NodeJS 应用程序设置基本 URL?

    我希望能够在同一域下托管多个 NodeJS 应用程序 而不使用子域 例如 google com reader 而不是 images google com 问题是我总是输入网址的第一部分 例如Express NodeJS 中的 reader
  • Bot Framework openUrl 不适用于信使上的建议操作

    我正在使用 Bot Builder Node js sdk 创建 facebook 机器人 并尝试创建建议操作 该操作将用户导航到网页 我知道 facebook 有限制 它仅重定向到 https 端点 但由于我重定向到的页面是 https
  • 为什么我在 Intellij IDEA 11 中调试 Nodejs 应用程序失败?

    我有一个单进程 node js 应用程序 我希望使用 Intellij IDEA 11 32 位进行调试 node js 也是 32 位 因此 我放置一个初始断点并运行 调试器在断点处停止 但随后拒绝执行以下任何操作 步入 转到另一个断点
  • 创建猫鼬模型时无法读取未定义的属性“用户”

    我正在尝试创建一个猫鼬模型并使用它从 mongodb 获取数据 但出现异常 我的 package json 中的猫鼬版本是 猫鼬 4 5 5 TypeError Cannot read property users of undefined
  • 我怎样才能摆脱错误:无法在 Heroku 上找到模块“模型”

    我在 Heroku 上不断收到此错误 错误 找不到模块 模型 我正在使用 Node JS 我在用着这个 Node JS 项目 https github com gravityonmars nodejs starter 我从 Heroku 复
  • Node.js 有水豚吗?

    有谁知道 Node js 是否有类似 capybara 的东西 怎么样Zombie http zombie labnotes org 僵尸 js 使用 Node js 进行极其快速的无头全栈测试 The Bite 如果你要编写一个速度极快的
  • MongoDB,从数组中删除对象

    Doc id 5150a1199fac0e6910000002 name some name items id 23 name item name 23 id 24 name item name 24 有没有办法从数组中提取特定对象 IE
  • 将 html2pdf 生成的 pdf 发送回服务器

    我必须使用以下命令发送客户端生成的 PDFhtml2pdf到服务器 我已成功将生成的 PDF 转换为 base64 并希望使用axios 这是我的客户端代码 function myFunction var element document
  • 节点:使用 Nodemailer 的直通流

    我正在使用officegen 生成一个Word 文档 然后计划使用Nodemailer 和Sendgrid 将其附加到电子邮件中 Officegen 输出一个流 但我更愿意将其直接传递到附件 而不是在本地保存 Word 文档然后附加它 Ge
  • Mongodb更新很多

    我正在使用express js 和 npm 模块 mongodb 进行开发 并以 mongodb 作为数据库 我有两个集合 即 用户 和 活动 一个用户可能有数千个活动 首先 我将用户的 id 姓名和图片 url 存储到 关系的活动文件 请
  • socket.io 作为客户端

    有什么方法可以将socketio作为客户端运行 不是浏览器 而是nodejs脚本 我需要将数据从服务器广播到一些客户端 浏览器 和另一台linux机器 仅运行nodejs来获取变量 没有浏览器 欢迎任何想法 Regards github上有
  • Nodejs 一个接一个地运行异步函数

    我是 JS nodejs 的新手 所以如果我不能提出切中要害的问题 请原谅我 所以基本上 如果我有两个异步函数 async function init async function main 如何确保在 init 完成其异步请求后调用 ma
  • 如何在 Node-Red 中的 oneditsave 之后在下拉列表中显示先前选择的值(动态)?

    我有一个自定义节点 其中包含两个彼此独立的下拉菜单 因此 第二个下拉列表值会根据第一个下拉列表中选择的值发生变化 我现在尝试的是 用户拖动我的自定义节点 iotinput 从两个拖放中选择值 按下并单击 完成 他再次拖动另一个自定义节点 i
  • 如何在 Google Translate Node.js 代码中设置 API KEY

    我正在尝试创建一个使用 Google Translate API 的 Node js 代码 我从以下代码中得到了谷歌文档 https cloud google com translate docs translating text 但是当我
  • 护照:登录和帐户注册的不同重定向

    我在我的应用程序中使用护照模块 github身份验证 我想根据操作进行重定向 我检查这是否只是正常登录或者用户是否第一次登录 passport use new GitHubStrategy clientID conf github app
  • 如何使用 Playwright 使用选择器查找框架 (iframe)

    我有一个小问题 无法找到使用 Microsoft Playwright 框架的答案 根据您可以使用以下代码获取 iframe const frame page frame frame login 但是如何使用选择器来查找 iframe 并与
  • 使用 AWS CDK 为 lambda 指定自定义角色

    我意识到它很新 但我没有看到任何语言的任何示例 说明如何为使用 AWS CDK 创建的 lambda 指定角色 我正在尝试这样做 const cdk require aws cdk cdk const lambda require aws
  • 如何清除NPM的https代理设置?

    如何清除NPM之前的ssl代理设置 好吧 我搜索了很多 但我得到的所有帖子主要是关于如何set公司网络中的代理 我尝试将代理设置为空 npm config set http proxy npm config set https proxy
  • 为 Node.js 客户端应用程序保留 Firebase 用户

    我正在使用 Firebase 构建 Node js 命令行界面 CLI 用于与后端进行身份验证 我想避免让用户每次运行命令时都输入密码 相反 我想实现一个 登录 流程 将凭证保留到文件系统 该凭证可用于后续的无密码身份验证 直到用户 注销

随机推荐

  • Ubuntu 14.04 64位上配置JDK操作步骤

    1 从 http www oracle com technetwork java javase downloads jdk8 downloads 2133151 html 下载jdk 8u172 linux x64 tar gz 2 解压缩
  • 软件测试期末总复习(知识点+习题+答案)

    目录 1 软件测试基础 1 1软件概述 1 1 1软件的生命周期 1 1 2 软件开发模型 1 1 3 软件质量概述 1 2 软件缺陷管理 1 2 1 软件缺陷产生的原因 1 2 2 软件缺陷的分类 1 2 3 软件缺陷的处理流程 1 3
  • jvm之java类加载机制和类加载器(ClassLoader)的详解

    当程序主动使用某个类时 如果该类还未被加载到内存中 则JVM会通过加载 连接 初始化3个步骤来对该类进行初始化 如果没有意外 JVM将会连续完成3个步骤 所以有时也把这个3个步骤统称为类加载或类初始化 一 类加载过程 1 加载 加载指的是将
  • 无线连接服务器 很慢,无线网很慢是什么原因

    大家好 我是时间财富网智能客服时间君 上述问题将由我为大家进行解答 无线网很慢的原因有 1 连接的网站所在的服务器带宽不足或负载过大 2 网线接触不良或者交换机的硬件原因导致 3 电脑本身存储文件过多等 所谓无线网络 是指无需布线就能实现各
  • 2022年天梯赛比赛真题,L1基础题,C语言,没有算法的那种

    目录 L1 1 今天我要赢 5 分 L1 2 种钻石 5 分 L1 3 谁能进图书馆 10 分 L1 4 拯救外星人 10 分 L1 5 试试手气 15 分 L1 6 斯德哥尔摩火车上的题 15 分 L1 7 机工士姆斯塔迪奥 20 分 L
  • spdk理解

    核跟线程的关系 在理解spdk 特别是spdk线程模型前 需要清楚cpu核跟线程的关系 首先 关于计算机系统的很多概念 都有 逻辑层 和 物理层 的区分 这个是前提 然后再看 核心 这个概念是 物理层 的概念 指的就是 CPU硬件的物理核心
  • OpenGL assimp库,编译 ‘File too big‘,‘too many sections’,IFCReaderGen.cpp 中报错

    QT环境下配置Assimp库 MinGW编译器 48条消息 QT环境下配置Assimp库 MinGW编译器 Elsa的迷弟的博客 CSDN博客 IFCReaderGen cpp 中报错 too many sections问题 如下图所示 此
  • SpringBoot整合kafka(实现consumer)

    如何在springboot中集成kafka收消息 1 pom xml引入依赖的jar包
  • 初始化和实例化的区别

    类的初始化 是完成程序执行前的准备工作 在这个阶段 静态的 变量 方法 代码块 会被执行 同时在会开辟一块存储空间用来存放静态的数据 初始化只在类加载的时候执行一次 类的实例化 是指创建一个对象的过程 这个过程中会在堆中开辟内存 将一些非静
  • php模式之装饰器模式2

    原文来自 大胖博客 在上一篇文章中 介绍了如何在代码架构之初 为了以后的扩展方便做的考虑 那么在现实中大部分的情况不是如此 那么我们需要重构这块么 不一定 今天我们使用另一种方式来实现装饰器 假设现在我们处在产品的第二个阶段 有下面第一阶段
  • 前端微信支付步骤(笔记)

    对接了两次微信支付 第一次对接的时候没有做记录下来 这一次把要记录下来 一 获取openId 1 在微信公众平台配置相关信息 具体按照微信官方文档步骤进行配置 mp weixin qq com wiki t reso 2 微信网页授权 文档
  • Js apply方法详解

    Js apply方法详解 主要解决一下几个问题 apply和call的区别在哪里 什么情况下用apply 什么情况下用call apply的其他巧妙用法 一般在什么情况下可以使用apply 首先从网上查到关于apply和call的定义 然后
  • 双重for循环删除数据

    1 倒过来遍历list for int i list size 1 i gt 0 i int item list get i if item 3 list remove item 2 每移除一个元素以后再把i移回来 for int i 0
  • Linux下CH452数码管芯片驱动调试(GPIO模拟I2C)

    1 设备连接 主控板处理器为Cortex A5处理器 内核4 9 0 主控板和CH452引脚定义如下表1 1所示 表1 1 主控板和CH452引脚定义 序号 CH452引脚定义 主控板引脚定义 1 SDA PB29 2 SCL PB30 3
  • 用树莓派搭建远程实时画面传输

    目录 一 材料准备 二 环境搭建 1 树莓派实现局域网监控画面传输 1 树莓派安装系统 2 将摄像头与树莓派连接 3 配置树莓派开发环境 4 让摄像头开始进行画面录制 5 将监控画面服务设置为开机自启 2 内网渗透 1 服务器端frp配置
  • AI考拉技术分享-Node基础架构专题

    前言 2018 年 考拉开始对现有项目的常用的工具库进行整理 包含日期处理 数字处理 logger 等常用工具 并打包成 npm module 方便各个项目使用 后期 我们也将重点分享这部分工具库的使用 大家感兴趣的一起来交流学习 有bug
  • Python爬虫能当副业吗?到了哪个层次能接单?解析能挣钱的方式

    多朋友问我学Python可不可以挣钱 答案是 当然可以 python爬虫肯定是可以当副业的 我身边一个伙伴就靠会python爬虫这一项技能一个月差不多能有一万多收入 他截图给我看的他的收入图是这样的 人家一个月就靠接单这个副业都比很多人主业
  • 开关电源环路稳定性分析(11)——观察法找零极点

    大家好 这里是大话硬件 这篇文章主要是分享如何用观察法直接写出补偿网络中的零极点的表达式 在前面的文章中 我们分别整理了OTA和OPA型的补偿网络 当时有下面的结论 针对某个固定的补偿网络 我们可以用数学的方法推导补偿网络的零极点 比如下面
  • ${ }的用法

    的用法 假设我们定义了一个变量为 file dir1 dir2 dir3 my file txt 我们可以用 分別替换获得不同的值 file 拿掉第一条 及其左边的字串 dir1 dir2 dir3 my file txt file 拿掉最
  • SetCallAsFunctionHandler 相当于lua __call

    首先到google开发者网站上下载v8源码 并按照说明进行编译 在v8中 编译和执行的js代码需要依付于一个空间 上下文 上下文由Context New创建 static Persistent