Node js собственный модуль, вызывающий обратный вызов из target- c прослушиватель событий блока не работает - PullRequest
1 голос
/ 02 мая 2020

Мне нужно создать модуль нативного узла, который прослушивает событие target- c OSX и запускает обратный вызов на javascript каждый раз, когда это происходит:

nativeAddon.listen(() => {
    console.log('It works!')
})

Обратный вызов работает, когда немедленно вызывается в функции setUpCallback, но не запускается из блока наблюдателя объектива - c.

Вот как выглядит мой файл main.mm

using namespace v8;

Local<Function> event_callback;

void setUpCallback(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    HandleScope scope(isolate);

    // Store the callback to be used in the runCallback function
    Local<Function> cb = Local<Function>::Cast(args[0]);
    event_callback = cb;

    // THIS WORKS
    runCallback();

    // Listen to a mac event and trigger the callback when it happens
    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserverForName:NSWorkspaceActiveSpaceDidChangeNotification object:NULL queue:NULL usingBlock:^(NSNotification *note) {
        // THIS DOESN'T WORK
        runCallback();
    }];
}

void runCallback() {
    auto isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    Local<Context> context = isolate->GetCurrentContext();

    Local<Value> argv[1] = { String::NewFromUtf8(isolate, "hello world", NewStringType::kNormal).ToLocalChecked() };

    auto fn = Local<Function>::New(isolate, event_callback);
    fn->Call(context, Null(isolate), 1, argv).ToLocalChecked();
}

void Initialize(Local<Object> exports) {
    NODE_SET_METHOD(exports, "listen", setUpCallback);
}

NODE_MODULE(addon, Initialize)

Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 02 мая 2020

Попробуйте изменить тип event_callback с Local<Function> на Persistent<Function>.

Время жизни Local связано с временем жизни HandleScope, в котором он был создан. Как только HandleScope выходит за пределы области (в вашем случае, в конце функции setUpCallback), все локальные элементы, созданные во время его работы, становятся недействительными. Если вам нужен дескриптор, который сохраняется после того, как HandleScope исчез, вам нужно использовать Persistent. Подробнее здесь: https://v8.dev/docs/embed#advanced -гид .

...