2

I'm trying to build a node-js wrapper for the C++ library Clip using the node addon api (N-NAPI). I want to retrive an image from a user's clipboard and pass it to JavaScript in a node.js buffer.

This is what I have tried: (only the relevant portions, rest is here)

Napi::Object get_image(const Napi::CallbackInfo& args) {
  Napi::Env env = args.Env();

  clip::image img;
  clip::get_image(img);

  clip::image_spec spec = img.spec();

  char *pixels = img.data();
  // since I dont know the length of pixels I use the width * height of the image
  Napi::Buffer<char> img_buffer = Napi::Buffer<char>::New(env, pixels, spec.width * spec.height);
  return img_buffer;
}

This compiles just fine but when I try to use it in JavaScript it results in a Segmentation fault (core dumped).

Example JS code:

const clip = require('bindings')('node_clip_wrapper')
console.log(clip.getImage())

How could I resolve this? Please excuse me if I am missing something basic, I am very new to C++ and building node addons.

x d
  • 473
  • 2
  • 4
  • 12

2 Answers2

1

The solution was to use Napi::Buffer::Copy instead of New. Documentation

Just Like this:

Napi::Buffer<char> img_buffer = Napi::Buffer<char>::Copy(env, pixels, spec.width * spec.height);
x d
  • 473
  • 2
  • 4
  • 12
1

I don't think Napi::Buffer::Copy will be a good solution since copying the underlying data is expensive.

Napi::Buffer::Newshould work as long as you keep the memory alive till JavaScript code is done with the Buffer object. In your case, the data pointed by pixels is de-allocated once the function returns.

Also you can use external buffer APIs to manage the memory by yourself: https://nodejs.org/api/n-api.html#napi_create_external_arraybuffer

Lin Jian
  • 66
  • 3