2

I have some constraints where the addon is built with nan.h and v8 (not the new node-addon-api).

The end function is a part of a library. It accepts std::vector<char> that represents the bytes of an image.

I tried creating an image buffer from Node.js:

const img = fs.readFileSync('./myImage.png');
myAddonFunction(Buffer.from(img));

I am not really sure how to continue from here. I tried creating a new vector with a buffer, like so:

std::vector<char> buffer(data);

But it seems like I need to give it a size, which I am unsure how to get. Regardless, even when I use the initial buffer size (from Node.js), the image fails to go through.

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
[1]    16021 abort (core dumped)

However, when I read the image directly from C++, it all works fine:

std::ifstream ifs ("./myImage.png", std::ios::binary|std::ios::ate);
std::ifstream::pos_type pos = ifs.tellg();
std::vector<char>  buffer(pos);
ifs.seekg(0, std::ios::beg);
ifs.read(&buffer[0], pos);

// further below, I pass "buffer" to the function and it works just fine. 

But of course, I need the image to come from Node.js. Maybe Buffer is not what I am looking for?

2
  • 1
    Maybe a tutorial on how to use Buffer from C++ is what you're looking for ;-) E.g.: community.risingstack.com/using-buffers-node-js-c-plus-plus Commented Nov 5, 2019 at 10:01
  • @jmrk I was actually searching for such a tutorial but could only find C++ to Node.js. Thank you! I'll take a look. Commented Nov 5, 2019 at 11:16

1 Answer 1

1

Here is an example based on N-API; I would also encourage you to take a look similar implementation based on node-addon-api (it is an easy to use C++ wrapper on top of N-API)
https://github.com/nodejs/node-addon-examples/tree/master/array_buffer_to_native/node-addon-api

#include <assert.h>
#include "addon_api.h"
#include "stdio.h"

napi_value CArrayBuffSum(napi_env env, napi_callback_info info)
{
    napi_status status;
    const size_t MaxArgExpected = 1;
    napi_value args[MaxArgExpected];
    size_t argc = sizeof(args) / sizeof(napi_value);

    status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    assert(status == napi_ok);
    if (argc < 1)
        napi_throw_error(env, "EINVAL", "Too few arguments");

    napi_value buff = args[0];
    napi_valuetype valuetype;
    status = napi_typeof(env, buff, &valuetype);
    assert(status == napi_ok);

    if (valuetype == napi_object)
    {
        bool isArrayBuff = 0;
        status = napi_is_arraybuffer(env, buff, &isArrayBuff);
        assert(status == napi_ok);

        if (isArrayBuff != true)
            napi_throw_error(env, "EINVAL", "Expected an ArrayBuffer");
    }

    int32_t *buff_data = NULL;
    size_t byte_length = 0;
    int32_t sum = 0;

    napi_get_arraybuffer_info(env, buff, (void **)&buff_data, &byte_length);
    assert(status == napi_ok);

    printf("\nC:  Int32Array size = %d,  (ie: bytes=%d)",
           (int)(byte_length / sizeof(int32_t)), (int)byte_length);
    for (int i = 0; i < byte_length / sizeof(int32_t); ++i)
    {
        sum += *(buff_data + i);
        printf("\nC:  Int32ArrayBuff[%d] = %d", i, *(buff_data + i));
    }

    napi_value rcValue;
    napi_create_int32(env, sum, &rcValue);

    return (rcValue);
}

The JavaScript code to call the addon

'use strict'
const myaddon = require('bindings')('mync1');

function test1() {
    const array = new Int32Array(10);

    for (let i = 0; i < 10; ++i)
        array[i] = i * 5;

    const sum = myaddon.ArrayBuffSum(array.buffer);
    console.log();
    console.log(`js: Sum of the array  = ${sum}`);
}

test1();

The Output of the code execution:

C:  Int32Array size = 10,  (ie: bytes=40)
C:  Int32ArrayBuff[0] = 0
C:  Int32ArrayBuff[1] = 5
C:  Int32ArrayBuff[2] = 10
C:  Int32ArrayBuff[3] = 15
C:  Int32ArrayBuff[4] = 20
C:  Int32ArrayBuff[5] = 25
C:  Int32ArrayBuff[6] = 30
C:  Int32ArrayBuff[7] = 35
C:  Int32ArrayBuff[8] = 40
C:  Int32ArrayBuff[9] = 45
js: Sum of the array  = 225
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.