简体   繁体   中英

how to deliver c++ array to node.js using v8 native addon

I implemented a c++ addon module that creates some buffer using unsigned char(uint8_t) memory and delivers it to node.js.

---- c++ addon.cpp ----

void get_frame_buffer(const FunctionCallbackInfo<Value>& args){
Isolate* isolate = helper.get_current_isolate();

if (!args[0]->IsUint32()&& !args[1]->IsUint32())
{
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong arguments")));
    return;
}

int width = args[0]->Uint32Value();
int height = args[1]->Uint32Value();

uint8_t* buf = new uint8_t[width * height * 4];
int length = width * height;
memset(buf, 0, sizeof(buf));

for (int i = 0; i < length; i++)
{
    buf[i * 4 + 0] = 128;
    buf[i * 4 + 1] = 128;
    buf[i * 4 + 2] = 128;
    buf[i * 4 + 3] = 255;
}       

Local<External> ext = External::New(isolate, buf);
Local<Object> obj = ext->ToObject();
args.GetReturnValue().Set(obj);
}

void Init(Local<Object> exports)
{     
  NODE_SET_METHOD(exports, "GetFrameBuffer", get_frame_buffer);
}

NODE_MODULE(glAddonNode, Init)

---- received.js in Node.js ----

const module = require('./addon.js');
var Received = function()
{
   this._module = new module.Module;
}

Received.prototype.get_frame_buffer = function(width, height)
{
  var c++_buf = this._module.GetFrameBuffer(width, height);
  // c++_buf is received from c++ addon
  // but c++_buf is null

  console.log(c++_buf);
}

Delivering object to node.js is successful, and I expected the array data to exist in the received object but that object is empty.

What's wrong?, is there a mistake in the code? How to deliver a c++ array to node.js using v8::External object? Or, do you know another way to deliver c++ array to node.js?

Additionally, I want to avoid copy functions (memcpy(), node::Buffer::Copy() etc..)

The short answer is: you cannot use v8::External s to expose C++ objects to JavaScript.

The intended use case for External s is to associate C++ objects with JS-exposed objects by storing them in "internal fields", which can only be accessed from C++. For example, you can store that uint8_t array (wrapped in an External ) in some object's internal field, and then when that object is handed from JS to one of your C++ callbacks, get the External from its internal field to retrieve the original uint8_t array. But there is no magic to expose a C++ array directly as object properties to JavaScript.

For fast sharing of binary data between C++ and JavaScript, node::Buffer s are probably what you want. Maybe this question: Pass Node.js Buffer to C++ addon is what you're looking for? This question: Node Buffer to char array provides code for conversions in both directions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM