nodejs / node-addon-api

Module for using Node-API from C++
MIT License
2.1k stars 457 forks source link

Query on reading/writing js typed arrays from C module. #1435

Closed pavanrust closed 5 months ago

pavanrust commented 6 months ago

Hi, I have a application which receives typed arrays from JS and is passed to C layer and vice versa. I convert the JS typed array into C array and pass it to C functions and similarly get C array and return to JS layer. I write/read the byte buffer of the ArrayBuffer of the typed array. Is this a good assumption or should I use any napi interface to read/write which I could not find such API's in C but seems to be there for CPP. Please suggest/correct.

I see the typed arrays documentation says to get a Dataview from the ArrayBuffer and then traverse from DataView. So should I create DataView from ArrayBuffer and then raw buffer from DataView and manipulate?

Following is write code from JS typed array to C array.

JS:
const float32arr = new Float32Array([32.12,12.2);

C Layer:
getCArr(napi_value value) {
   void *data = NULL;
   napi_typedarray_type type;
   size_t num, bytOffset = 0;
   napi_value arrBuf;
   // get typed array , value information 
   napi_get_typedarray_info(env, value, &type, &num, &data,
                &arrBuf, &byteOffset);

   // copy to C float array
   float *farr = (float *) malloc(num * 4);
   if (type == napi_float32_array) {
     memcpy(farr, data + byteOffset, num * 4);

   }

   // print array 
   for (int i = 0; i < num; i++) {
     printf(" Ele %f \n", farr[i]);
   }
}

Following is read code from C array and construct a JS typed array.

getJSarray(float *farr, size_t len,  napi_value *value) {
     size_t byteLength = len * 4;
     size_t  bufferOffset = 0;
     void *data = NULL;
     napi_value arrBuf;
     napi_create_arraybuffer(env, byteLength, 
            &data, &arrBuf))
    napi_create_typedarray(
            env, napi_float32_array, numElem, arrBuf, bufferOffset, value);
    memcpy(data, farr, byteLength); 
}
gabrielschulhof commented 6 months ago

@pavanrust I think your usage pattern is correct. The purpose of typed arrays is to make transferring large amounts of data between JS and native code more efficient by making sure that the native view of the data is memory-contiguous, the way C data is. In fact, assuming that the C side reads/modifies the typed array within the same call, you need not even copy it, which will further improve performance.

pavanrust commented 6 months ago

Thanks @gabrielschulhof for confirming. Yes i will directly use the raw bytes in C without copy..