Node.js C++ 附加组件尝试使用 `require` 函数执行 javascript 代码
Node.js C++ add-on trying to execute javascript code with `require` function
我正在用 C++ 维护一个 Node.js 附加组件。
我需要在异步调用的 C++ 函数中调用 SQL 解析器(实际上是 SQL 的一个非常不标准的变体),但不幸的是(对我来说)解析器已经实现在 Javascript 中使用一些 Node.js 库(正在使用函数 require
);这是我需要执行的 javascript 代码的示例:
require("./util/SqlParser")("SELECT 1 FROM DUAL").getSyntaxTree()
我试过这样写:
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::TryCatch trycatch;
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate
,
"require(\"./util/SqlParser\")(\"SELECT 1 FROM DUAL\").getSyntaxTree()"
,
v8::NewStringType::kNormal).ToLocalChecked()
;
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
v8::MaybeLocal<v8::Value> result = script->Run(context);
if( result.IsEmpty() )
{
v8::Local<v8::Value> exc = trycatch.Exception();
if( !exc.IsEmpty() )
{
auto msg = exc->ToString();
if( !msg.IsEmpty() )
throw std::string( *v8::String::Utf8Value(msg) );
}
throw "unknown error in called js function";
}
但不幸的是,这不起作用。最终结果是错误消息 "ReferenceError: require is not defined"
:显然,我的上下文对 Node.js.
一无所知
我试图将上面的表达式包装在一个 js 函数中 parseSqlText
,但是脚本执行程序同样不知道这个函数(我收到错误消息 "ReferenceError: parseSqlText is not defined"
)。
我的问题是:有什么办法可以解决这个问题吗?
如有任何帮助,我们将不胜感激。我会很高兴避免在 C++ 中重新实现该解析器...目前这似乎是完成我需要的唯一可行方法。
我建议您去找一个 已经用 C++ 编写 的 SQL 解析器。我在 github.com
.
上进行了十秒钟的搜索,立即 找到了一个
在我看来,将 JavaScript 语言引入这种情况的技术理由为零,只是为了能够 "parse SQL." 您根本不需要 "write from scratch" 任何东西.它只是一个对象 – 将其提取 "off the shelf," 实例化它的一个实例,然后使用它。
- 首先,v8 不是 Node.js,Node.js是建立在v8之上的。
- v8 是一个 javascript 引擎
- 因此Node.js v8 本身不携带库
N-API 是问题的答案。虽然,通常它用于为 Node.js 编写本机 C++ 插件。 github thread belwo 有一些例子。此外,还链接了 N-API 的 node.js 文档。
Github Thread
Node N-API Docs
编辑:看起来工作已经完成了,在这里 repository。作者这样做是为了让它看起来抽象了 v8 的所有准备工作,并成为您的一行。
#include "node_embed.h"
int main(int argc, char** argv) {
node_context *context = nodeSetup(argc, argv);
if (context) {
nodeExecuteString(context, "let foo = 1", "__init__");
nodeExecuteString(context, "foo = 2", "__init__");
nodeExecuteString(context, "console.log(foo)", "__init__");
return nodeTeardown(context);
} else {
return 12;
}
}
以上内容来自存储库,您可以运行那段代码。
我正在用 C++ 维护一个 Node.js 附加组件。
我需要在异步调用的 C++ 函数中调用 SQL 解析器(实际上是 SQL 的一个非常不标准的变体),但不幸的是(对我来说)解析器已经实现在 Javascript 中使用一些 Node.js 库(正在使用函数 require
);这是我需要执行的 javascript 代码的示例:
require("./util/SqlParser")("SELECT 1 FROM DUAL").getSyntaxTree()
我试过这样写:
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::TryCatch trycatch;
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate
,
"require(\"./util/SqlParser\")(\"SELECT 1 FROM DUAL\").getSyntaxTree()"
,
v8::NewStringType::kNormal).ToLocalChecked()
;
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
v8::MaybeLocal<v8::Value> result = script->Run(context);
if( result.IsEmpty() )
{
v8::Local<v8::Value> exc = trycatch.Exception();
if( !exc.IsEmpty() )
{
auto msg = exc->ToString();
if( !msg.IsEmpty() )
throw std::string( *v8::String::Utf8Value(msg) );
}
throw "unknown error in called js function";
}
但不幸的是,这不起作用。最终结果是错误消息 "ReferenceError: require is not defined"
:显然,我的上下文对 Node.js.
我试图将上面的表达式包装在一个 js 函数中 parseSqlText
,但是脚本执行程序同样不知道这个函数(我收到错误消息 "ReferenceError: parseSqlText is not defined"
)。
我的问题是:有什么办法可以解决这个问题吗?
如有任何帮助,我们将不胜感激。我会很高兴避免在 C++ 中重新实现该解析器...目前这似乎是完成我需要的唯一可行方法。
我建议您去找一个 已经用 C++ 编写 的 SQL 解析器。我在 github.com
.
在我看来,将 JavaScript 语言引入这种情况的技术理由为零,只是为了能够 "parse SQL." 您根本不需要 "write from scratch" 任何东西.它只是一个对象 – 将其提取 "off the shelf," 实例化它的一个实例,然后使用它。
- 首先,v8 不是 Node.js,Node.js是建立在v8之上的。
- v8 是一个 javascript 引擎
- 因此Node.js v8 本身不携带库
N-API 是问题的答案。虽然,通常它用于为 Node.js 编写本机 C++ 插件。 github thread belwo 有一些例子。此外,还链接了 N-API 的 node.js 文档。
Github Thread
Node N-API Docs
编辑:看起来工作已经完成了,在这里 repository。作者这样做是为了让它看起来抽象了 v8 的所有准备工作,并成为您的一行。
#include "node_embed.h"
int main(int argc, char** argv) {
node_context *context = nodeSetup(argc, argv);
if (context) {
nodeExecuteString(context, "let foo = 1", "__init__");
nodeExecuteString(context, "foo = 2", "__init__");
nodeExecuteString(context, "console.log(foo)", "__init__");
return nodeTeardown(context);
} else {
return 12;
}
}
以上内容来自存储库,您可以运行那段代码。