gpt4 book ai didi

c++ - Node js 原生模块,从 Objective-C block 事件监听器触发回调不起作用

转载 作者:行者123 更新时间:2023-12-03 17:18:27 28 4
gpt4 key购买 nike

我需要创建一个 native Node 模块来监听 Objective-C OSX 事件,并在每次发生时触发对 javascript 的回调:

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

回调在 setUpCallback 函数中立即调用时起作用,但它不会从 Objective-C 观察者 block 触发。

这是我的 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)

任何帮助将不胜感激!

最佳答案

我正在使用 node-addon-api 并尝试了 @jmrk 的解决方案,但它对我不起作用。将类型更改为“持久”还不够。

所以我在 GitHub 上问了这个问题 here .

因为 Mac 事件是在单独的线程中触发的,所以需要使用 ThreadSafeFunction .

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#include <napi.h>

Napi::ThreadSafeFunction tsfn;

// Trigger the JS callback when active space changes
void listenForActiveSpaceChange(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();

// Create a ThreadSafeFunction
tsfn = Napi::ThreadSafeFunction::New(
env,
info[0].As<Napi::Function>(), // JavaScript function called asynchronously
"Active Space", // Name
0, // Unlimited queue
1 // Only one thread will use this initially
);

// Create a native callback function to be invoked by the TSFN
auto callback = [](Napi::Env env, Napi::Function jsCallback) {
// Call the JS callback
jsCallback.Call({});
};

// Subscribe to macOS spaces change event
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserverForName:NSWorkspaceActiveSpaceDidChangeNotification
object:NULL
queue:NULL
usingBlock:^(NSNotification *note) {
// Perform a blocking call
napi_status status =
tsfn.BlockingCall(callback);
if (status != napi_ok) {
NSLog(@"Something went wrong, BlockingCall failed");
}
}];
}

Napi::Object init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "listenForActiveSpaceChange"),
Napi::Function::New(env, listenForActiveSpaceChange));

return exports;
};

NODE_API_MODULE(mac_helper, init);

关于c++ - Node js 原生模块,从 Objective-C block 事件监听器触发回调不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61555053/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com