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;
    }
}

以上内容来自存储库,您可以运行那段代码。