Node.js C ++ add-on пытается выполнить код javascript с функцией `require` - PullRequest
0 голосов
/ 14 декабря 2018

Я поддерживаю надстройку Node.js в C ++.

Мне нужно вызвать синтаксический анализатор SQL (на самом деле очень нестандартный вариант SQL) внутри асинхронно вызываемой функции C ++, нок сожалению (для меня), этот парсер был реализован в 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 ++ ... который в настоящее время кажется единственным жизнеспособным способом сделать то, что мне нужно.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018
  • Во-первых, v8 - это , а не Node.js, Node.js построен поверх v8.
  • v8 - это движок JavaScript
  • Таким образом, NodeБиблиотеки .js не переносятся с v8 самим собой

    . N-API является ответом на вопрос.Хотя обычно он используется для написания собственных плагинов C ++ для Node.js.У github thread belwo есть несколько примеров.Кроме того, документы node.js для N-API также были связаны.
    Github Thread
    Узел N-API Docs

РЕДАКТИРОВАТЬ: Казалось бы, работа уже выполнена, здесь, в этом репозиторий .Автор сделал это так, что он, кажется, абстрагирует всю подготовительную работу 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;
    }
}

Вышеприведенный фрагмент взят из репозитория и позволит вам запустить этот фрагмент кода.

0 голосов
/ 14 декабря 2018

Я предлагаю вам найти анализатор SQL, который уже написан на C ++.Я нашел один немедленно в десятисекундном поиске по github.com.

По моему мнению, нет никакого технического обоснования для включения языка JavaScript в этот сценарий, просто чтобы иметь возможность"разбирать SQL."Вам вообще не придется ничего «писать с нуля».Это будет просто объект - возьмите его «с полки», создайте его экземпляр и используйте его.

...