标签: n-api

从C ++ Node.js插件调用现有的JavaScript函数-从另一个线程调用

也许我只是没有搜索正确的词,但是我被困住了。

我需要从C ++调用JavaScript函数,这与使用普通C API可以完成的操作非常相似。

注:我希望传递一个回调到C ++代码,但我已经知道要调用的函数的名称!

因此,例如,我在JavaScript中具有以下功能:

function log_message_callback(context, message) {
  console.log(`${context}: ${message}`);
}

my_napi_module.initialize();   // <-- starts thread that would call log_message_callback

Run Code Online (Sandbox Code Playgroud)

从C ++我想调用它(顺便说一句,来自与主线程不同的线程):

function log_message_callback(context, message) {
  console.log(`${context}: ${message}`);
}

my_napi_module.initialize();   // <-- starts thread that would call log_message_callback

Run Code Online (Sandbox Code Playgroud)

我可以这样做吗?我该怎么做?我应该一直在寻找什么?

javascript c++ node.js n-api

8
推荐指数
2
解决办法
271
查看次数

使用 N-API 将数据流式传输到 Node.js C++ 插件

我正在为 NodeJS 构建一个 C++ 插件,我想将数据从 C++ 异步传输到 Node。但是,我找到了这篇文章https://nodeaddons.com/streaming-data-into-a-node-js-c-addon/;我想使用 N-API 而不是 NAN。

我一直在搜索 NodeJS 文档和示例,并寻找其他资源和示例,但还没有找到一个资源来向我展示如何实现这一点。这是我第一次为 NodeJS 编写 C++ 插件。

一个可以帮助我入门的示例是一个插件,它使用 N-API 每秒向 Node 发送一个虚拟字符串,然后 Node 会将字符串打印到控制台。

c++ node.js node.js-addon n-api node-addon-api

7
推荐指数
1
解决办法
2014
查看次数

如何将 C++ 类返回给 NODE.JS

设置:
我有一个 NODE.JS 应用程序,它必须以低延迟执行一些计算
我决定使用 N-API 和 node-gyp 将本机 C++ 模块包含到 NODE.JS 应用程序中

当前状态:
我到了工具链工作的地步,我可以将 C++ 源代码编译成二进制文件,在 NODE.JS 应用程序中包含二进制模块,NODE.JS 应用程序执行
我可以使用标准 NODE.JS 调用 C++ 方法来自 NODE.JS 的类型和方法可以在执行完成后将标准的 NODE.JS 类型返回给 NODE.JS

问题:
我不知道如何将自定义类型/对象从 C++
返回到 NODE.JS目前我想基本上返回一个具有多种类型的结构,以便将复杂解析的结果返回到 NODE.JS 中单个 NODE.JS 调用

最少的代码输出:
我做了一个最少的实现来演示我想做的事情。如果你评论#define ENABLE_RETURN_CLASS代码只使用标准的 NODE.JS 类型并且一切正常。在输出图像下方,显示工具链和执行按预期工作:
浮动工程

如果离开#define ENABLE_RETURN_CLASS,代码将无法编译。据我所知,它不明白如何从 C++ 对象转换为 NODE.JS 对象。这是错误: 在此处输入图片说明

最少代码:
初始化 NODE.JS 应用程序

npm init
npm install node-gyp --save-dev
npm install node-addon-api
Run Code Online (Sandbox Code Playgroud)

将 C++ 二进制文件编译为 NODE.JS 模块

npm run build
Run Code Online (Sandbox Code Playgroud)

启动 NODE.JS 应用程序

node main.js …
Run Code Online (Sandbox Code Playgroud)

c++ node.js node-gyp n-api

7
推荐指数
1
解决办法
2045
查看次数

如何从插件中的单独 C++ 线程调用发射器回调?

对于上下文,我从这个问题开始。我需要在另一个线程中调用发射器的回调。我做了一个最小的例子,但它出现了段错误emit.Call({cb, result});我的第一直觉是我的生命周期envemit函数有问题。

插件.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)

c++ multithreading node.js node.js-addon n-api

6
推荐指数
1
解决办法
1860
查看次数

如何使用 node-addon-api 保存回调以供稍后使用?

我希望我的 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.js node.js-addon n-api

5
推荐指数
1
解决办法
1245
查看次数

如何异步使用node-addon-api的AsyncContext

的文档AsyncContext具有可同步工作的此示例(仅作了少许修改,但仍可正常工作):

#include "napi.h"

void MakeCallbackWithAsyncContext(const Napi::CallbackInfo& info)
{
  Napi::Function callback = info[0].As<Napi::Function>();
  Napi::Object resource = info.Env().Global().As<Napi::Object>();;    
  Napi::AsyncContext context(info.Env(), "async_context_test", resource);

  callback.MakeCallback(Napi::Object::New(info.Env()),
      std::initializer_list<napi_value>{}, context);
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何异步使用它-这是我的最新照片:

Napi::AsyncContext* _context;
Napi::FunctionReference* _callback;
Napi::Object* _resource;

void CallBack()
{
  _callback->MakeCallback(*_resource, std::initializer_list<napi_value>{}, *_context);
}

void MakeCallbackWithAsyncContext(const Napi::CallbackInfo& info)
{
  Napi::Function cb = info[0].As<Napi::Function>();
  _callback = new Napi::FunctionReference(Napi::Persistent(cb));
  _callback->SuppressDestruct();

  _resource = new Napi::ObjectReference(Napi::Persistent(env.Global()));
  _resource->SuppressDestruct();

  _context = new Napi::AsyncContext(info.Env(), "async_context_test", _resource->Value());

  // run CallBack() in different thread
}
Run Code Online (Sandbox Code Playgroud)

程序内部崩溃CallBack()

node.js node.js-addon n-api node-addon-api

5
推荐指数
1
解决办法
247
查看次数

如何将 napi_threadsafe_function 用于 NodeJS Native Addon

我一直在浏览NAPI 文档,试图了解它是如何处理multithreading. 根据文档napi_create_threadsafe_function()napi_call_threadsafe_function()用于js functions从多个线程创建和调用。问题是文档不是那么直截了当,并且没有示例,我在其他任何地方都找不到。

如果有人有任何使用经验napi_create_threadsafe_function()和/napi_call_threadsafe_function()或知道在哪里可以找到使用它们的示例。请如果你能帮助一个基本的例子,这样我就可以理解如何正确使用它们。

我正在C编写一个插件,而不是C++需要使用这些功能。我没有使用包装器node-addon-api,而是napi直接使用

c asynchronous node.js-addon n-api

4
推荐指数
1
解决办法
2117
查看次数

如何使用返回承诺的 NAPI 创建异步函数

我正在尝试使用 NAPI 创建节点模块。我必须创建返回承诺的异步函数。我不希望 testasynfunction 会阻塞 NodeJS 事件循环。do_something_asynchronous 是一个同步函数。

napi_deferred do_something_synchronous(napi_env env,napi_deferred deferred){
  printf("\n3) Function called");
  //napi_deferred deferred;
  napi_value undefined;
  napi_status status;

  // Create a value with which to conclude the deferred.
  status = napi_get_undefined(env, &undefined);
  if (status != napi_ok) return NULL;
  sleep(5);
  // Resolve or reject the promise associated with the deferred depending on
  // whether the asynchronous action succeeded.
  if (false) {
    printf("\n5) Success\nXXXXXXX");
    status = napi_resolve_deferred(env, deferred, undefined);
  } else {
    printf("\nReject");
    status = napi_reject_deferred(env, deferred, undefined);
  } …
Run Code Online (Sandbox Code Playgroud)

javascript asynchronous node.js promise n-api

4
推荐指数
1
解决办法
1008
查看次数

如何在 Node v10 的 Google Cloud Functions 中使用 ffi-napi

我在 Google Cloud Function (Node v10) 中遇到了本机模块依赖项(特别是 IBM MQ for js)的问题,并且没有找到我需要的任何信息,所以我打开了这个问题并回答了自己以允许其他人将来找到它。

它在 Node v8 引擎中运行良好,但现在已弃用。将引擎升级到 v10 并碰撞一些包(遵循有关我的依赖项的所有迁移指南)后,ffi-napi包在 期间抛出异常yarn install,如下所示:

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: ...s status = napi_get_instance_data(env, &d);
                        ^~~~~~~~~~~~~~~~~~~~~~
../src/ffi.cc:11:24: note: suggested alternative: 'napi_new_instance'
   napi_status status = napi_get_instance_data(env, &d);
                        ^~~~~~~~~~~~~~~~~~~~~~
                        napi_new_instance
../src/ffi.cc: In function 'Napi::Object BindingHook(Napi::Env, Napi::Object)':
../src/ffi.cc:347:24: error: 'napi_set_instance_data' was not declared in this scope
   napi_status status = napi_set_instance_data(
                        ^~~~~~~~~~~~~~~~~~~~~~
../src/ffi.cc:347:24: note: suggested alternative: 'napi_new_instance'
   napi_status status = napi_set_instance_data(
                        ^~~~~~~~~~~~~~~~~~~~~~
                        napi_new_instance
In file …
Run Code Online (Sandbox Code Playgroud)

node.js google-cloud-platform google-cloud-functions ibm-mq n-api

3
推荐指数
1
解决办法
536
查看次数