用Node-addon-api实现C++调用Javascript
作者:互联网
本文介绍在使用Node-addon-api时,能够实现用C++调用Javascript的几种方式。
1. Callback
比较简单,示例:
Napi::Function cb = info[0].As<Napi::Function>();
cb.Call(env.Global(), { Napi::String::New(env, "hello world") });
Return function
String MyFunction(const CallbackInfo& info) {
Env env = info.Env();
return String::New(env, "hello world");
}
Function CreateFunction(const CallbackInfo& info) {
Env env = info.Env();
Function fn = Function::New(env, MyFunction, "funName");
return fn;
}
2. 带有ThreadSafeFunction的callback(可以在C++中另写线程重复调用JS)
Napi::Value callback(const Napi::CallbackInfo &info)
{
Napi::Env env = info.Env();
if ( info.Length() < 2 )
{
throw Napi::TypeError::New( env, "Expected two arguments" );
}
else if ( !info[0].IsFunction() )
{
throw Napi::TypeError::New( env, "Expected first arg to be function" );
}
else if ( !info[1].IsNumber() )
{
throw Napi::TypeError::New( env, "Expected second arg to be number" );
}
int count = info[1].As<Napi::Number>().Int32Value();
// Create a ThreadSafeFunction
tsfn = Napi::ThreadSafeFunction::New(
env,
info[0].As<Napi::Function>(), // JavaScript function called asynchronously
"Resource Name", // Name
0, // Unlimited queue
1, // Only one thread will use this initially
[]( Napi::Env ) { // Finalizer used to clean threads up
nativeThread.join();
} );
// Create a native thread
nativeThread = std::thread( [count] {
auto callback = []( Napi::Env env, Napi::Function jsCallback, int* value ) {
// Transform native data into JS data, passing it to the provided
// `jsCallback` -- the TSFN's JavaScript function.
jsCallback.Call( {Napi::Number::New( env, *value )} );
// We're finished with the data.
delete value;
};
for ( int i = 0; i < count; i++ )
{
// Create new data
int* value = new int( clock() );
// Perform a blocking call
napi_status status = tsfn.BlockingCall( value, callback );
if ( status != napi_ok )
{
// Handle error
break;
}
std::this_thread::sleep_for( std::chrono::seconds( 1 ) );
}
// Release the thread-safe function
tsfn.Release();
} );
return Napi::Boolean::New(env, true);
}
JS:
dlxPlugin.callback(() => {
console.log("C++ call javascript function");
}, 2)
3. Event
Napi::Value event(const Napi::CallbackInfo &info)
{
Napi::Env env = info.Env();
Napi::Function emit = info[0].As<Napi::Function>();
emit.Call({ Napi::String::New(env, "msg"), Napi::Number::New(env, 1) });
emit.Call({ Napi::String::New(env, "msg"), Napi::Number::New(env, 10) });
}
JS:
const eventListener = new EventEmitter();
eventListener.on("msg", (data) => {
console.log("Msg:", data);
}
)
event(eventListener.emit.bind(eventListener));
4. 调用JS-eval,直接运行字符串
globalThis.num = 1; console.log(nw.test()); console.log(globalThis.num); // 2
Napi::String jsStr = Napi::String::New(env, "num++"); napi_value result; napi_run_script(env, jsStr, &result); return Napi::Value::From(env, result);
可以这样运行函数
globalThis.xx = () => { return 233; } console.log(nw.test()); // 233
Napi::String jsStr = Napi::String::New(env, "xx()");
使用eval
globalThis.num = 1; console.log(nw.test()); console.log(globalThis.num); // 2
auto eval = env.Global().Get("eval").As<Napi::Function>(); return eval.Call(env.Global(), {Napi::String::New(env, "num++")});
标签:Node,info,Env,Javascript,C++,env,New,Napi,String 来源: https://www.cnblogs.com/Asp1rant/p/15031229.html