Search code examples
c++cnode-addon-api

node-addon-api how to pass int pointer back and forth between JS and C/C++


I have the following backend functions:

// foo.c

void cStart(pid_t* pid)
{
  *pid = getpid();

  // event-loop keep running until receive SIGINT signal
}

void cStop(pid_t* pid)
{
  kill(*pid, SIGINT);
}
// addon.cpp

#include "addon.h"
#include "foo.h"

Napi::Number addon::run_pipeline_wrapped(const Napi::CallbackInfo &info)
{
  Napi::Env env = info.Env();

  // get the buffer from JS, pass it to cStart to be modified in-place [?]
  cStart(pid_t* pid);
}

Napi::Number addon::kill_pipeline_wrapped(const Napi::CallbackInfo &info)
{ 
  Napi::Env env = info.Env();

  // get the modified (by cStart) buffer from JS, pass it to cStop [?]
  cStop(pid_t* pid);
}

From the front-end, when the start button is clicked, a C process will start running until it receive a SIGINT signal and when the stop button is clicked, SIGINT signal is sent to the running C process. int* will travel as follow: JS (start button clicked) -> C/C++ (cStart modified int* in place so int* is not explicitly returned to JS) -> JS (stop button clicked) -> C/C++). So how do I pass an int pointer back and forth between JS and C/C++?


Solution

  • You don't have to pass pointer to JS.

    You can use a global state instead:

    // foo.c
    
    pid_t* my_pid;
    
    void cStart(void)
    {
      my_pid = getpid(); // save the pid
    
      // event-loop keep running until receive SIGINT signal
    }
    
    void cStop(void)
    {
      // kill the process from earlier
      kill(*my_pid, SIGINT);
    }
    
    

    Note, however this assumed that you had only one which isn't changed by anything else between calling cStart and calling cEnd. So in cEnd it should kill the same process on which the start button has been clicked.

    Your C++ code will then look like this:

    // addon.cpp
    
    #include "addon.h"
    #include "foo.h"
    
    Napi::Number addon::run_pipeline_wrapped(const Napi::CallbackInfo &info)
    {
      Napi::Env env = info.Env();
      cStart();
    }
    
    Napi::Number addon::kill_pipeline_wrapped(const Napi::CallbackInfo &info)
    { 
      Napi::Env env = info.Env();
      cStop();
    }