我正在开发本机 Node.js 插件并关注nan docs
我将 nan 包含到 binding.gyp 中,例如:
"include_dirs" : [ "<!(node -e \"require('nan')\")" ]
nan 也在 npm 依赖项中。
但是当我在另一个节点模块中安装包时,node-gyp 失败并出现错误
> nnb@1.0.2 install /Users/Shopgate/sandbox/stress/node_modules/nnb
> node-gyp rebuild
module.js:338
throw err;
^
Error: Cannot find module 'nan'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at [eval]:1:1
at Object.exports.runInThisContext (vm.js:74:17)
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:460:26)
at evalScript (node.js:431:25)
at startup (node.js:90:7)
gyp: Call to 'node -e "require('nan')"' returned exit status 1. while trying …Run Code Online (Sandbox Code Playgroud) 我有一些现有的C++代码,可以在独立的C++应用程序中进行数值处理.我现在想在新的node.js应用程序中使用该代码.
研究如何从node.js访问C++代码,有两个选项:
node-ffi似乎是访问现有库的一个很好的选择,但我是否正确地思考如果我使用node-ffi我将不得不编写一个C包装器来使我的C++可访问?(这是我可以通过Visual Studio在Windows上使用简单的测试用例的唯一方法).
对于我的情况,我的源代码已经在C++中,而不是C,在上面两个选项之间选择有哪些注意事项?
我正在寻找一个使用带有C ++的node js插件的项目。我遇到了两个我可以使用的抽象库NAN和N-API。但是,我无法决定应该使用哪一个。我无法在这两个库之间找到适当的比较。
两者的优缺点是什么?如何在它们之间进行选择?
到目前为止,我发现NAN有更多关于异步调用的在线教程/文章。但是N-API受到Node的正式支持(虽然不确定,但它是在NAN之后创建的,是更好的选择)。
我正在编写一个自定义node.js插件,由C++与C程序混合使用.
addon.cc包含类似的内容
#define BUILDING_NODE_EXTENSION
#include <node.h>
#include <node_buffer.h>
using namespace v8;
using namespace node;
/* other logic and function... */
Handle<Value> RunCallback(const Arguments& args) {
HandleScope scope;
Local<Value> buffer1 = args[0];
size_t size = Buffer::Length(buffer1->ToObject());
char* bufferdata = Buffer::Data(buffer1->ToObject());
/* some logic written in C style ... */
Local<Function> cb = Local<Function>::Cast(args[1]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(String::New(outputdata, outputSize)) };
cb->Call(Context::GetCurrent()->Global(), argc, argv);
return scope.Close(Undefined());
}
void Init(Handle<Object> target) {
target->Set(String::NewSymbol("runCallback"), FunctionTemplate::New(RunCallback)->GetFunction());
}
NODE_MODULE(addon, Init)
Run Code Online (Sandbox Code Playgroud)
它还包括其他.cc文件,所以wscript是这样的: …
我正在尝试将外部C++库(我可以访问.so文件以及头文件)集成到我的Node.js应用程序中.
经过大量研究后,我的选择减少到:
从node-ffi的gitHub的定义我无法判断它是否会直接在C++库上运行:
node-ffi是一个Node.js插件,用于使用纯JavaScript加载和调用动态库.它可用于创建与本机库的绑定,而无需编写任何C++代码.
所以我的问题是:
I'm no expert when it comes to C/C++ so if I missed something basic for you to be able to answer please let me know so I can improve my question.
我需要在我的C++插件中使用内置模块'crypto'的node.js.我试图找到使用内置模块的C++插件的例子,但是失败了.我查看了node_crypto.h/.cc,与node.js加密文档,受保护的构造函数等相比,它具有如此不同的函数签名.node_crypto.h包含带有一个参数的InitCrypto()声明,但是node_crypto.cc没有这样的定义.功能.只有InitCrypto有四个参数.我试过用一个参数使用InitCrypto并得到"符号查找错误".
我可以将require('crypto')的结果传递给我的插件,然后使用这个对象,但这是不安全的.我们的JS代码可以在客户端的服务器上运行.
现在我觉得C++插件使用像openssl lib而不是内置节点模块'crypto'的smth更简单.
所以我需要一些使用C++插件的工作示例,它使用'crypto'模块或链接到一些关于此的文章.
使用C++插件中的任何内置模块的任何示例都会有所帮助.
正常C++ execl工作正常(编译g++ ok.cc -o ok.elf)
#include <unistd.h>
int main(){
execl("/usr/bin/python", "/usr/bin/python", nullptr);
}
Run Code Online (Sandbox Code Playgroud)
但崩溃时,作为node.js C++插件工作
#include <node.h>
#include <unistd.h>
namespace bug{
void wtf(const v8::FunctionCallbackInfo<v8::Value>& args){
execl("/usr/bin/python", "/usr/bin/python", nullptr);
}
void init(v8::Local<v8::Object> exports){
NODE_SET_METHOD(exports, "wtf", bug::wtf);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, init)
}
Run Code Online (Sandbox Code Playgroud)
node.js v8.9.1
node-gyp v3.6.2
gcc版本6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2)
我正在为 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 会将字符串打印到控制台。
我发现*v8 :: String :: Utf8Value(args [0] - > ToString())在节点0.8.2 32位上返回正确的字符串,并且不在节点0.8.8上返回正确的字符串64-位.
有谁知道为什么?
我的node.js插件看起来像这样:
#define BUILDING_NODE_EXTENSION
#include <node.h>
#define MAX_OUTPUT_BUF 80
extern "C" char *do_sqlsig(char *in);
using namespace v8;
Handle<Value> Sqlsig(const Arguments& args) {
HandleScope scope;
char *c_arg, *ret;
if (args.Length() < 1) {
ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
return scope.Close(Undefined());
}
c_arg = *v8::String::Utf8Value(args[0]->ToString());
ret = c_arg; //do_sqlsig(c_arg);
return scope.Close(String::New(ret));
}
void Init(Handle<Object> exports) {
exports->Set(String::NewSymbol("sqlsig"),
FunctionTemplate::New(Sqlsig)->GetFunction());
}
NODE_MODULE(sqlsig, Init)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在为C函数do_sqlsig编写一个包装器.我非常了解C并且对C++知之甚少
对于上下文,我从这个问题开始。我需要在另一个线程中调用发射器的回调。我做了一个最小的例子,但它出现了段错误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) node.js-addon ×10
node.js ×9
c++ ×6
v8 ×3
c ×2
n-api ×2
node-ffi ×2
crash ×1
javascript ×1
linux ×1
node-gyp ×1
node.js-nan ×1
npm ×1
unistd.h ×1