Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

returning synchronous array in c++ addon #194

Open
Mohamadhj opened this issue Apr 16, 2022 · 10 comments
Open

returning synchronous array in c++ addon #194

Mohamadhj opened this issue Apr 16, 2022 · 10 comments

Comments

@Mohamadhj
Copy link

Hello everyone,

I have a c++ code that I'm using nan to be able to implement it in nodejs environment. The problem is, my code has an while loop and wants to send an array for each loop to the nodejs, but I can only send one array in the addon with args.GetReturnValue.Set() or info.GetReturnValue.Set(). Is there a way to continously send data rather than just returning one value at the end of the addon?

Appreciating any help.

@mhdawson
Copy link
Member

I think you likely want to use a ThreadSafe Function to pass data back to the main thread each time you want to send data

@Mohamadhj
Copy link
Author

@mhdawson It worked like you said. but it took sometime for me get familiarized with what Threadsafe Functions are and how to implement them.
Thank you so much for the help!

@Mohamadhj
Copy link
Author

@mhdawson I have a question, can we still use the Threadsafe function using only C addon, i.e include <node_api.h> and not <napi.h> and thus not relying on C++ classes like Napi:Function, Napi:Value , and so on? thank you for the help!

@Mohamadhj Mohamadhj reopened this Apr 29, 2022
@mhdawson
Copy link
Member

I think you can use the Threadsafe APIs in C, @gabrielschulhof do you know if we have any examples of that?

@Mohamadhj
Copy link
Author

Mohamadhj commented May 3, 2022

@mhdawson Thanks, I found a Threadsafe example in C. But I have a question: I want to do two callbacks as opposed to one in the javascript callback, Like this:

test.startThread((theprime) =>{
msg.payload=theprime;node.send(msg);})

(I'm using Node-RED to send a message across)

Is this possible ? because we're only calling one callback:

size_t argc = 1;
status = napi_get_cb_info(env,
info,
&argc,
&js_cb,
NULL,
(void**)(&addon_data));

Thanks already for your help

@Mohamadhj
Copy link
Author

@mhdawson Nevermind I used the curly braces (javascript newbie here)

@mhdawson
Copy link
Member

mhdawson commented May 4, 2022

@mhdawson Nevermind I used the curly braces (javascript newbie here)

good to hear you have what you need. Can this be closed?

@Mohamadhj
Copy link
Author

@mhdawson Yes, I will close it now.

@Mohamadhj
Copy link
Author

Mohamadhj commented May 24, 2022

@mhdawson I have a small problem occuring related to the same code, would really appreciate your help.

I followed the example of a [async_work_thread_safe_function], and my code is successfully sending arrays of number of elements up to 6, however, when I increase the number of elements of the array being sent the program crashes, I will attach the code that will make the problem clearer. The arrays are real-time recorded data from an osciloscope. Do you think I can't send more than 6 each time because the code can't catch up with the osciloscope because a lot of processing is involved and I shall reduce the number of array elements?

static void CallJs(napi_env env, napi_value js_cb, void* context, void* data) {
    // This parameter is not used.
    (void)context;
    napi_status status;
    napi_value result;
    napi_value undefined;
    napi_create_array_with_length(env,8, &result);

    status = napi_get_undefined(env, &undefined);
    assert(status == napi_ok);
    double(*test)[8] = (double(*)[8])data;
    napi_value e;

    for (int i = 0; i < 8; i++) {
        // Retrieve the prime from the item created by the worker thread.
        status = napi_create_double(env, (*test)[i], &e);
        napi_set_element(env, result, i, e);

    }
    // env and js_cb may both be NULL if Node.js is in its cleanup phase, and
    // items are left over from earlier thread-safe calls from the worker thread.
    // When env is NULL, we simply skip over the call into Javascript and free the
    // items.


    // Convert the integer to a napi_value.

    assert(status == napi_ok);

    // Retrieve the JavaScript `undefined` value so we can use it as the `this`
    // value of the JavaScript function call.

    // Call the JavaScript function and pass it the prime that the secondary
    // thread found.


    status = napi_call_function(env,
        undefined,
        js_cb,
        8,
        &result,
        NULL);
    assert(status == napi_ok);


    // Free the item created by the worker thread.
    free(data);
}
static void ExecuteWork(napi_env env, void* data) {

while(cSamples<nSamples){
// processing to get the samples from the oscilosope. Real time
// array in the next inscrutcion is the array which I'm changing the number of elements to
 status = napi_call_threadsafe_function(addon_data->tsfn, array, napi_tsfn_nonblocking);
            assert(status == napi_ok);
            status = napi_release_threadsafe_function(addon_data->tsfn,
                napi_tsfn_release);
            assert(status == napi_ok);
        }

@Mohamadhj Mohamadhj reopened this May 24, 2022
@mhdawson
Copy link
Member

When you say crashed do you mean a SIGSEGV or running out of memory? Off the top of my head I can't see why more than 6 would be a problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants