I have some C functions that I need to call frequently from nodeJS (less than 1 second time intervals). The C function takes in an argument and returns a value, which might be an int or an array.
It can be as simple as below:
int main() {
int x = 2;
return x;
}
And I need to get the value x in nodeJS and be able to do console.log(x)
I tried using node-ffi
, but I read from the internet that it has a large overhead and is thus inefficient for frequent function calls.
I also considered writing addons but it seems very troublesome (with unfamiliar V8, C++ code and all that...)
And there is not much resources regarding integration between nodeJS and C (they are mostly nodeJS with C++)
Could somebody help shed some light on this? Thanks.
js can dynamically load an external C or C++ DLL file at runtime and utilize its API to perform some operations written inside it from a JavaScript program. This is basically how a Native Addon works in Node.
js Addons are dynamically-linked shared objects, written in C++, that can be loaded into Node. js using the require() function, and used just as if they were an ordinary Node. js module. They are used primarily to provide an interface between JavaScript running in Node.
js Foreign Function Interface for N-API. node-ffi-napi is a Node. js addon for loading and calling dynamic libraries using pure JavaScript. It can be used to create bindings to native libraries without writing any C++ code. It also simplifies the augmentation of node.
libuv: libuv is a C library originally written for Node. js to abstract non-blocking I/O operations. Event-driven asynchronous I/O model is integrated. It allows the CPU and other resources to be used simultaneously while still performing I/O operations, thereby resulting in efficient use of resources and network.
change your c code to
// myProgram.c
#include <stdio.h>
int main(void){
puts("4");
return 0;
}
compile it with gcc, in the same directory as your node file
$ gcc -o myProgram myProgram.c
in your node file, require exec()
const { exec } = require("child_process");
and use it like so:
exec("./myProgram", (error, stdout, stderr) => console.log(stdout));
This works well, it spins up a new process every time.
If, on the other hand, you want to keep the child process running, and call a function in that code from node, you can do that like this:
// multiplyBy2.c
#include <stdio.h>
#include <stdlib.h>
int timesTwo(int x){
return x*2;
}
int main(void){
char buff[100];
int input,output;
while(1){
gets(buff);
input = atoi(buff);
output = timesTwo(input);
printf("%d", output);
// you must flush stdout or else node will hang!
fflush(stdout);
}
return 0;
}
compile multiplyBy2.c and then:
// myNodeApp.js
const {spawn} = require('child_process');
const __delay__ = t => new Promise(resolve=>setTimeout(()=>resolve(), t))
const ch = spawn('./multiplyBy2')
var result=undefined;
ch.stdout.on("data",(data)=>{
result = parseInt(data.toString())
})
async function multiplyBy2InC(num){
ch.stdin.write(`${num}\n`)
while(result==undefined)
await __delay__(1)
const output = result
result = undefined
return output
}
// now you could call it like this, it will print 20 to the console
multiplyBy2InC(10).then(r=>console.log(r))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With