Calling a v8 javascript function from c++ with an argument

2023-11-20

I am working with c++ and v8, and have run into the following challenge: I want to be able to define a function in javascript using v8, then call the function later on through c++. Additionally, I want to be able to pass an argument to the javascript function from c++. I think the following sample source code would explain it best. Check towards the end of the sample code to see what I am trying to accomplish.

#include <v8.h>
#include <iostream>
#include <string>
#include <array>

using namespace v8;

int main(int argc, char* argv[]) {

    // Create a stack-allocated handle scope.
    HandleScope handle_scope;

    // Create a new context.
    Persistent<Context> context = Context::New();
    Context::Scope context_scope(context);
    Handle<String> source;
    Handle<Script> script;
    Handle<Value> result;

    // Create a string containing the JavaScript source code.
    source = String::New("function test_function(test_arg) { var match = 0;if(test_arg[0] == test_arg[1]) { match = 1; }");

    // Compile the source code.
    script = Script::Compile(source);

    // What I want to be able to do (this part isn't valid code..
    // it just represents what I would like to do.
    // An array is defined in c++ called pass_arg,
    // then passed to the javascript function test_function() as an argument
    std::array< std::string, 2 > pass_arg = {"value1", "value2"};
    int result = script->callFunction("test_function", pass_arg);

}

Any tips?

UPDATE:

Based on the advice given, I have been able to put together the following code. It has been tested and works:

#include <v8.h>
#include <iostream>
#include <string>

using namespace v8;

int main(int argc, char* argv[]) {

// Create a stack-allocated handle scope.
HandleScope handle_scope;

// Create a new context.
Persistent<Context> context = Context::New();

//context->AllowCodeGenerationFromStrings(true);

// Enter the created context for compiling and
// running the hello world script.
Context::Scope context_scope(context);
Handle<String> source;
Handle<Script> script;
Handle<Value> result;


// Create a string containing the JavaScript source code.
source = String::New("function test_function() { var match = 0;if(arguments[0] == arguments[1]) { match = 1; } return match; }");

// Compile the source code.
script = Script::Compile(source);

// Run the script to get the result.
result = script->Run();
// Dispose the persistent context.
context.Dispose();

// Convert the result to an ASCII string and print it.
//String::AsciiValue ascii(result);
//printf("%s\n", *ascii);

Handle<v8::Object> global = context->Global();
Handle<v8::Value> value = global->Get(String::New("test_function"));
Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value);
Handle<Value> args[2];
Handle<Value> js_result;
int final_result;

args[0] = v8::String::New("1");
args[1] = v8::String::New("1");

js_result = func->Call(global, 2, args);
String::AsciiValue ascii(js_result);

final_result = atoi(*ascii);

if(final_result == 1) {

    std::cout << "Matched\n";

} else {

    std::cout << "NOT Matched\n";

}

return 0;

}
asked  Jul 8 '12 at 21:53
user396404
1,151 5 19 33
 
 
I assume that IsInt32 returns true, but Int32Value returns 0? –  Nate Kohl  Jul 10 '12 at 19:36
 
Check out my edit -- maybe we're not passing enough parameters... –  Nate Kohl  Jul 10 '12 at 19:52
 
You have a mistake in your code: you dispose the current context and after you are using it. You must put the dispose line at the end of your program. –  banuj  Jun 5 '13 at 8:20 

2 Answers

up vote 11 down vote accepted

I haven't tested this, but it's possible that something like this will work:

// ...define and compile "test_function"

Handle<v8::Object> global = context->Global();
Handle<v8::Value> value = global->Get(String::New("test_function")); 

if (value->IsFunction()) {
    Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value);
    Handle<Value> args[2];
    args[0] = v8::String::New("value1");
    args[1] = v8::String::New("value2");

    Handle<Value> js_result = func->Call(global, 2, args);

    if (js_result->IsInt32()) {
        int32_t result = js_result->ToInt32().Value();
        // do something with the result
    }
}

Edit:

It looks like your javascript function expects a single argument (consisting of an array of two values), but it kinda looks like we're calling func by passing in two arguments.

To test this hypothesis, you could change your javascript function to take two arguments and compare them, e.g.:

function test_function(test_arg1, test_arg2) { 
  var match = 0; 
  if (test_arg1 == test_arg2) { 
    match = 1; 
  } else { 
    match = 0; 
  } 
  return match; 
}
answered  Jul 8 '12 at 23:58
Nate Kohl
18.4k 7 33 46
 
 
It seems to be working. I'm having trouble using js_result though. The part where it says if(js_result.IsInt32) is giving the following error during compile time: error: ‘class v8::Handle<v8::Value>’ has no member named ‘Int32’| –  user396404  Jul 10 '12 at 0:36 
1  
@user396404: maybe try js_result->IsInt32() instead? –  Nate Kohl  Jul 10 '12 at 11:26
 
That did work. The code compiles, but it is not returning a value of 1 even if the values match :/ –  user396404  Jul 10 '12 at 19:20
 
Thanks for all the help. It turns out I had to reference the variables using the arguments array, instead of test_arg1 and test_arg2. For anyone reading this in the future, the part where it says Call(global, 2, args), the 2 represents the length of the args array. I posted the revised and working code in my original answer. Thanks for all the help! –  user396404  Jul 10 '12 at 23:00

Another simpler method is as follows:

Handle<String> code = String::New(
  "(function(arg) {\n\
     console.log(arg);\n\
    })");
Handle<Value> result = Script::Compile(code)->Run();
Handle<Function> function = Handle<Function>::Cast(result);

Local<Value> args[] = { String::New("testing!") };
func->Call(Context::GetCurrent()->Global(), 1, args);

Essentially compile some code that returns an anonymous function, then call that with whatever arguments you want to pass.

answered  Jun 4 '13 at 17:50
jkp
33.7k 18 83 95
 
 
v8::ScriptCompiler::CompileFunctionInContext does the "wrap your code in a function" bit for you. –  xaxxon Oct 11 at 21:19
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Calling a v8 javascript function from c++ with an argument 的相关文章

  • 构建:找不到“节点”的类型定义文件

    VS 2015 社区版 在家 npm 3 10 Angular 2 我试图在 ASP Net MVC 5 应用程序中获取 Angular2 设置 我开始使用的模板使用旧版本的 Angular 因此我更新了包引用 当我构建时 列表中的第一个错
  • Docker - SequelizeConnectionRefusedError:连接 ECONNREFUSED 127.0.0.1:3306

    我正在尝试使用 Docker 容器启动并运行我的 Nodejs 应用程序 我不知道可能出了什么问题 当我使用控制台调试凭据时 凭据似乎已正确传递 另外启动sequel pro并使用相同的用户名和密码直接连接似乎也可行 当节点在容器中启动时
  • 从节点服务器访问 Google Calendar API

    由于某种原因 我很难访问 Google 日历 我希望能够在 Node js 服务器的日历中添加和删除事件 我从文件中发现了非常矛盾的信息 我跟着 https developers google com identity protocols
  • MongoDB中如何通过引用字段进行查询?

    我有两个 Mongo 模式 User id ObjectId name String country ObjectId Reference to schema Country Country id ObjectId name String
  • 最小验证在 Mongoose 中不起作用

    我有一个架构 其中余额字段的声明如下所示 balance type Number min 0 default 30 我将 0 设置为最小值 这样余额就不会为负值 但是当我通过更新查询减少余额值时 余额结果是负值 我的更新查询 User up
  • 如何阻止 Node.js 服务器崩溃

    我是节点js新手 我试图创建一个简单的 HTTP 服务器 我按照著名的例子创建了一个 Hello World 服务器如下 var handleRequest function req res res writeHead 200 res1 e
  • NPM 无法在 Windows 上安装“truffle”

    我正在尝试使用 npm 安装 truffle 但我不熟悉 NodeJS 并且不明白为什么 npm 不会安装它 我尝试npm install g truffle在具有管理员权限的 Powershell 中 经过几行输出后 我收到以下错误消息块
  • 如何使用 Protractor 检查某个元素是否不可点击?

    测试一个元素是否很简单is可使用量角器点击 但我一直在挠头试图弄清楚如何检查元素是否not可点击 我尝试将 click 函数包装在 try catch 中 这样当尝试单击时抛出错误时 它应该捕获它并让测试通过 然而 这不起作用 这是我执行检
  • Express中间件修改请求

    我目前有一个正在运行的服务器 前端使用nodejs mongo express 和 W2UI W2ui 请求来自包含所有参数的记录数组 记录 名称 foo 我想编写一个中间件 在请求到达路由之前对其进行编辑和更改 您可以创建自己的中间件来处
  • 在ubuntu 12.04上安装nodejs和npm后找不到.npmrc文件

    我刚刚按照教程在我的 ubuntu 12 04 上安装了 nodejs 和 npm https gist github com dwayne 2983873 https gist github com dwayne 2983873 现在安装
  • 呃!尝试将包发布到 npm 时出现 403

    我正在尝试将包发布到 npm 您可以在此处查看存储库 https github com biowaffeln mdx state https github com biowaffeln mdx state 我登录到 npmnpm login
  • 尝试安装 LESS 时出现“请尝试以 root/管理员身份再次运行此命令”错误

    我正在尝试在我的计算机上安装 LESS 并且已经安装了节点 但是 当我输入 node install g less 时 出现以下错误 并且不知道该怎么办 FPaulMAC bin paul npm install g less npm ER
  • 使用socket.io进行用户身份验证

    我已经红色了这个教程 http howtonode org socket io auth http howtonode org socket io auth 它展示了如何使用express和socket io对用户进行身份验证 但是有没有一
  • 为什么 Node.js 应用程序只能从 127.0.0.1/localhost 访问?

    我本来打算教我的朋友介绍 Node 但是后来 我想知道为什么这个代码来自nodejs org var http require http http createServer function req res res writeHead 20
  • Jwt 签名和前端登录身份验证

    我有这个特殊的 jwt sign 函数 Backend const token jwt sign id user id process env TOKEN SECRET expiresIn 1m res header auth token
  • npmjs.org - 找不到自述文件

    我是 npm 包的主要作者scramjet 一个月以来 我遇到了关于可视性的问题README md在 npmjs 中 The npm 中的超燃冲压发动机包 https www npmjs com package scramjet shows
  • Node.js 重写 toString

    我试图覆盖我的对象的默认 toString 方法 这是代码和问题 function test this code 0 later on I will set these this name test prototype toString f
  • editMessageReplyMarkup 方法删除内联键盘

    我正在使用 node js 制作一个电报机器人node telegram bot api图书馆 我回答callback query并想更换我的内联键盘 下面的代码显示了我如何尝试使用此方法 但是当我在电报中点击键盘时 它就消失了 bot o
  • nodemon 安装错误“没有可用于超时的有效版本”

    尝试在全新的节点项目中安装 nodemon 时出现此错误 我创建了一个名为 my project 的空白文件夹 然后 在其中 我执行了创建一个 package json 文件 npm init f 然后当尝试运行时 npm install
  • 如何使用Create React App安装React

    嗨 我对反应真的很陌生 我不知道如何实际安装它 也不知道我需要做什么才能在其中编写代码 我下载了node js并且安装了v12 18 3以及NPM 6 14 6 但是每次我尝试在许多网站上提到的create react app安装方法中输入

随机推荐

  • 项目中:Json文件的读取

    项目中 Json文件的读取 读Json文件 取Json文件中内容 举例 举例 Json文件内容如下 Flickr8k images sentids 39300 39301 39302 39303 39304 imgid 7860 sente
  • C++11中 std::bind 的两种用法

    概述 std bind的头文件是
  • hadoop环境搭建之关闭防火墙和SELinux

    每一台服务器上都要做1 2 1 关闭防火墙 查看防火墙状态 systemctl status firewalld 关闭防火墙 systemctl disable firewalld systemctl stop firewalld 查看防火
  • iOS 获取系统键盘UIKeyboard方法

    公司项目需求 需要让弹窗显示在键盘所在的图层之上 而不是在弹窗出现的时候消失 如图1 系统弹窗出现的时候会使键盘暂时不显示 而这种效果显然不符合要求的 由于没想到更好的办法 只好从键盘自身的UIKeyboard做文章了 通过获取当前键盘的U
  • 【Java多线程批量数据导入的方法】

    前言 当遇到大量数据导入时 为了提高处理的速度 可以选择使用多线程来批量处理这些处理 常见的场景有 大文件导入数据库 这个文件不一定是标准的CSV可导入文件或者需要在内存中经过一定的处理 数据同步 从第三方接口拉取数据处理后写入自己的数据库
  • 按装完mysql怎么启动_mysql安装完怎么启动服务器?

    mysql安装完启动服务器的方法 1 打开 开始 菜单 依次点击 管理工具 服务 打开系统服务窗口 2 在 服务 窗口中找到 MySQL 右击选择 启动 命令就可以启动mysql服务器了 mysql 是世界流行的开源数据库系统 下面本篇文章
  • 关于TypeScript和React的使用

    TS和React的使用 接口与类型 type与interface 内置的语法糖 Partial和Required Readonly Omit Exclude 继承 接口与类型 type与interface 内置的语法糖 Partial和Re
  • ffmpeg错误码

    cpp view plain copy AVERROR BSF NOT FOUND 1179861752 AVERROR BUG 558323010 AVERROR DECODER NOT FOUND 1128613112 AVERROR
  • 数字化转型中的国产化替代之路

    引言 数字经济浪潮席卷全球 我国数字经济已进入快速发展阶段 加快推进企业数字化转型 已成为共识 同时有利于构建全产业链数字化生态 增强产业链上下游的自主可控能力 为数字经济社会发展 构建数智化生态注入新动能 在此过程中 国产软件企业作为数字
  • python利用tushare下载数据并计算当日收益率

    python利用tushare下载数据并计算当日收益率 计算股票收益率的程序主要有以下几部分构成 1 获取股票接口数据函数 pro daily stock 2 计算收益率函数 cal stock 里面有两种计算式 你可以根据自己字典写入建仓
  • 堆排序的topk问题+归并排序+六大排序总结

    回忆一下堆排序 思路 sift函数 调整 将父亲和孩子 左孩子和右孩子中最大的那个数 然后和父亲比较 如果孩子大就将孩子的位子变为下一个父亲 往下拉 并且将孩子的值赋给他的父亲 j lt high 条件认可 防止父亲在最后一层 魔法般的对应
  • Tensorflow的Win10、CPU版本安装

    1 Anaconda的安装 Miniconda的安装 Anaconda的安装链接 https www anaconda com products distribution 如图所示 点击箭头所指 可以安装anaconda的最新版本 Mini
  • elementui 禁止浏览器自动填充用户名密码

    浏览器这功能在登录的时候挺好用的 但是在注册和管理的时候就很难受了 所以 在普通的input上直接off就行了
  • 华为虚拟机服务器怎么使用教程,虚拟机装服务器教程

    虚拟机装服务器教程 内容精选 换一换 应用容器化改造有三种方式 您可单击这里查看 本教程以某游戏为例 将该游戏进行微服务的架构改造 再进行容器化 本教程不对改造细节做深度讲解 仅讲解大致的建议 如需要详细了解容器化改造的过程 请单击服务咨询
  • 攻防世界adworld-hit-the-core

    hit the core 题目来源 CTF 题目描述 暂无 题目附件 下载附件 kwkl kwkl strings home kwkl 桌面 8deb5f0c2cd84143807b6175f58d6f3f core CORE code c
  • 【视频流上传播放功能】前后端分离用springboot-vue简单实现视频流上传和播放功能【详细注释版本,包含前后端代码】

    前言 我是前端程序猿一枚 不是后端的 如有写的有不规范的地方别介意哈 自己摸索了两天算是把这个功能做出来了 网上看了很多帖子没注释说实话 我看的基本是懵逼的 毕竟没有系统学过 所以现在做出来了就总结一下 自己多写点注释解释一下逻辑 让前端的
  • SpringBoot+MyBatisPlus+Thymeleaf+AdminLTE增删改查实战

    说明 AdminLTE是网络上比较流行的一款Bootstrap模板 包含丰富的样式 组件和插件 非常适用于后端开发人员做后台管理系统 因为最近又做了个后台管理系统 这次就选的是AdminLTE做主题模板发现效果不错 这里我把最核心的Spri
  • 华为机考练习python

    HJ108 求最小公倍数 while True try a b map int input split for i in range 1 b 1 if a i b 0 print a i break except break HJ107 求
  • linux中256错误,YUM安装遭遇: [Errno 256] No more mirrors to try

    把YUM配置好后 使用yum命令进行安装时 出现了如下错误 Downloading Packages ftp 192 168 220 46 RHEL6 2 x64 Server libaio devel 0 3 107 10 el6 x86
  • Calling a v8 javascript function from c++ with an argument

    Calling a v8 javascript function from c with an argument up vote 18 down vote favorite 8 I am working with c and v8 and