对于上下文,我从这个问题开始。我需要在另一个线程中调用发射器的回调。我做了一个最小的例子,但它出现了段错误emit.Call({cb, result});我的第一直觉是我的生命周期env或emit函数有问题。
插件.cpp
#include <napi.h>
#include <iostream>
#include <thread>
#include <memory>
#include <functional>
#include <chrono>
std::shared_ptr<std::thread> thread;
bool running = true;
void generate(Napi::Env& env, Napi::Function& emit)
{
while(running)
{
Napi::Array result = Napi::Array::New(env);
for(int i = 0; i < 3; ++i)
{
result[i] = rand()%100;
}
auto cb = Napi::String::New(env, "onFeedData");
emit.Call({cb, result});
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
Napi::Value Start(const Napi::CallbackInfo& info)
{
Napi::Env env = info.Env();
Napi::Function emit = info[0].As<Napi::Function>();
auto cb = …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用nan来计算附加组件中浮点数组上的某些内容,然后将其作为Float32Array.
但是,虽然 args 具有IsNumber()和NumberValue()功能,但它只有一个IsFloat32Array()功能而没有Float32Array()。
NAN_METHOD(Calc) {
NanScope();
if (args.Length() < 2) {
NanThrowTypeError("Wrong number of arguments");
NanReturnUndefined();
}
if (!args[0]->IsNumber() || !args[1]->IsFloat32Array()) {
NanThrowTypeError("Wrong arguments");
NanReturnUndefined();
}
/* a vector of floats ? */ args[0]-> ???;
double arg1 = args[1]->NumberValue();
// some calculation on the vector
NanReturnValue(/* Return as a Float32Array array */);
}
Run Code Online (Sandbox Code Playgroud) 想象一下,我使用 Node.js 插件中的同步函数:
var check_ok = addon.my_function(parameters);
var final_results = addon.final_function(parameters);
Run Code Online (Sandbox Code Playgroud)
但在方法代码中我有:
std::thread t[10]; //Global
//...
void my_function(const FunctionCallbackInfo<v8::Value>& args) {
//....
t[0] = thread(random_void_function, [parameters])
t[1] = thread(random_void_function_2, [parameters])
//...
}
//...
void final_results(const FunctionCallbackInfo<v8::Value>& args) {
//...
t[0].join();
t[1].join();
//...Give results.. etc
}
Run Code Online (Sandbox Code Playgroud)
所以我有两个插件的同步调用,但在这个插件中使用了两个线程。一个函数将启动线程,另一个函数将加入它们。问题是:random_void_function并且random_void_function_2会并行运行吗?既然my_function和final_function是同步的,那么random_void_function和random_void_function_2会阻塞事件循环吗?据我所知,他们没有阻止。
我正在为 Node.js 编写 C++ 插件。尝试使用名为 libSample.so 的示例库,它具有函数 printHello 的声明:
void printHello() {
std::cout << "Hello World\n";
}
Run Code Online (Sandbox Code Playgroud)
它工作正常。(使用编译node-gyp configure build并执行node ./)
当我尝试使用另一个更复杂的库 libCore.so 时。开始执行时产生以下错误。编译配置通过发现:
module.js:597
return process.dlopen(module, path._makeLong(filename));
^
Error: libPlayerCore.so: cannot open shared object file: No such file or directory
at Error (native)
at Object.Module._extensions..node (module.js:597:18)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/home/jasurn/CLionProjects/JsTest/hello.js:2:15)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
Run Code Online (Sandbox Code Playgroud)
一些用法 libCore.so
//#include <core.h> definition …Run Code Online (Sandbox Code Playgroud) 我正在为 C++ 库构建一个节点模块包装器,以通过Nan将日志信息传递给 JavaScript。为此,可以使用 NAN_Method 来注册回调。回调处理程序必须通过vlAddLogListener(). 的LoggingCallbackHandler在函数从库接收到一个消息dispatchEvent,一个C ++函数。如果我收到日志,我想调用 JavaScript 回调来传递数据。
该函数dispatchEvent不是在 Nan 上下文中调用的,因此我没有范围/上下文,也无法访问 v8。如何调用 JavaScript 回调?
代码如下所示:
NAN_METHOD(registerLoggingCallback)
{
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Function> fun = info[0].As<v8::Function>();
lch = new LoggingCallbackHandler(isolate, fun);
}
LoggingCallbackHandler::LoggingCallbackHandler(v8::Isolate* isolate, v8::Local<v8::Function> fun) :
_cb(isolate, fun)
{
vlAddLogListener(&LoggingCallbackHandler::dispatchEvent, this);
}
void VL_CALLINGCONVENTION LoggingCallbackHandler::dispatchEvent(const char* eventData, void* clientData)
{
// here I want to process the data and call the JavaScript callback
v8::Local<v8::Function> f = v8::Local<v8::Function>::New(Nan::GetCurrentContext()->Global()->GetIsolate(), _cb); …Run Code Online (Sandbox Code Playgroud) 我正在使用N-API(C 接口,不要与围绕 N-API的node-addon-api C++ 包装器混淆)为 Node.js 编写一个插件,它从外部源接收 JSON 格式的数据并且需要在其对象形式上执行 JS 回调函数。但是,在将 JSON 格式的数据传递到 JS 回调之前,我无法将其解析为插件内的正确对象(即,由 JSON.parse 生成),并且似乎只能在其文本中传递它形式。
到目前为止,我发现的唯一示例涉及直接使用C++ NAN和 V8 API。我错过了什么吗?我应该对 JSON.parse 进行另一个 napi_call_function 调用,捕获它的返回值,然后传递它吗?(如果是这样,我如何从我的插件中获取 JSON.parse 回调信息?)有没有我没有找到的更简单的 API?
出于多种原因,我更愿意使用 C,而不是 C++,尽管我认为这是可以协商的。
foo.js
const myaddon = require('bindings')('myaddon');
const EventEmitter = require('events').EventEmitter;
const emitter = new EventEmitter();
emitter.on('eventReceived', (foo) => {
var obj = JSON.parse(foo); // *** this is what I'd like to avoid ***
console.log(obj.bar);
})
myaddon.RegisterForEvents(emitter.emit.bind(emitter));
Run Code Online (Sandbox Code Playgroud)
我的插件
void AsyncComplete(napi_env env, napi_status status, void * data) …Run Code Online (Sandbox Code Playgroud) 我尝试使用此\nbinding.gyp 文件配置并构建一个node.js C++ 插件:
\n\n{ \n "targets": [\n {\n "target_name": "addon",\n "sources": [ "addon.cpp" ],\n "cflags": [\n "-std=c++17"\n ] \n }\n ]\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但当我跑步node-gyp configure时node-gype rebuild n我总是收到类似的消息
\n\n\n警告:\xe2\x80\x98if constexpr\xe2\x80\x99 仅适用于 -std=c++17 或 -std=gnu++17
\n
构建也失败了,因为我真的依赖于这些 c++17 功能。我究竟做错了什么?
\n我很难理解如何正确使用HandleScope和EscapeableHandleScope。例如,从这个节点示例:
MyObject::MyObject(const Napi::CallbackInfo& info) : Napi::ObjectWrap<MyObject>(info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
this->val_ = info[0].As<Napi::Number>().DoubleValue();
};
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下我们需要创建一个新的 HandleScope?从另一个例子来看:
Napi::Object CreateObject(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Object obj = Napi::Object::New(env);
obj.Set(Napi::String::New(env, "msg"), info[0].ToString());
return obj;
}
Run Code Online (Sandbox Code Playgroud)
为什么这里不需要呢?
另外,我没有找到任何使用 EscapeableHandleScope 的示例,什么时候需要这个?
我希望我的 C 库能够多次调用 JS 函数。我使用 Nan 让它工作,但在将其转换为 N-API/node-addon-api 时遇到问题。
如何保存 JS 回调函数并稍后从 C 调用它?
这是我使用 Nan 得到的结果:
Persistent<Function> r_log;
void sendLogMessageToJS(char* msg) {
if (!r_log.IsEmpty()) {
Isolate* isolate = Isolate::GetCurrent();
Local<Function> func = Local<Function>::New(isolate, r_log);
if (!func.IsEmpty()) {
const unsigned argc = 1;
Local<Value> argv[argc] = {
String::NewFromUtf8(isolate, msg)
};
func->Call(Null(isolate), argc, argv);
}
}
}
NAN_METHOD(register_logger) {
Isolate* isolate = info.GetIsolate();
if (info[0]->IsFunction()) {
Local<Function> func = Local<Function>::Cast(info[0]);
Function * ptr = *func;
r_log.Reset(isolate, func);
myclibrary_register_logger(sendLogMessageToJS);
} else { …Run Code Online (Sandbox Code Playgroud) 我目前正在寻找带有 node-gyp 的 C++ 附加组件。
node-gyp configure工作正常,但node-gyp build给出了一个错误
error C2661: 'v8::Value::ToNumber': no overloaded function take 0 parameter。
有一些关于已弃用的警告,它们提供了一个链接到 v8.h 文件(在 node-gyp 中)的声明。但是,关于ToNumber 的只有V8_DEPRECATED 和V8_WARN_UNUSED_RESULT。因此,似乎由于缺少关于v8::Value::ToNumberin的定义而导致错误v8.h。
错误发生在下面的最后一行代码:
void someFunction(const FunctionCallbackInfo<Value>& args) {
Isolate *iso = args.GetIsolate();
if (args.Length() < 1) {
iso->ThrowException(Exception::TypeError(String::NewFromUtf8(iso, "Must provide Input")));
}
Local<Object> coords = args[0]->ToObject()->Clone(); // note that the keys are available with coords->GetOwnPropertyNames();
Local<Array> keys = coords->GetOwnPropertyNames();
if (keys->Length() != 2) {
iso->ThrowException(Exception::TypeError(String::NewFromUtf8(iso, "Need exactly 2 values")));
} …Run Code Online (Sandbox Code Playgroud) node.js ×10
node.js-addon ×10
c++ ×6
javascript ×3
v8 ×3
n-api ×2
add-on ×1
c++17 ×1
nan ×1
node-gyp ×1
node.js-nan ×1
node.js-napi ×1