0

I have compiled a C program (array.out compiled from array.c in linux) which returns a pointer to an array of doubles.

array.c:

#include <stdio.h>
#include <stdlib.h>

double* main(int argc, char *argv[]){
    double *arr;
    arr = (double *)calloc((3), (unsigned)(sizeof(double)));
    arr[0] = 10;
    arr[1] = 20;
    arr[3] = 30;
    return arr;
}

I also have a running express nodejs server:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
})

Is there a way to call that c program (array.out) and handle its response(arr) in express nodeJs server?

5
  • yeah, through a http server .. notwithstanding the general error noted below Commented Jun 5, 2021 at 8:25
  • 3
    The main in C cannot return an array of double. It has to return an int that is passed back to the shell as result code. Commented Jun 5, 2021 at 8:25
  • You can make an C++ addon Commented Jun 5, 2021 at 8:26
  • 2
    You can write your C program to output the array of double to stdout and the from node.js execute that program and grab the output. See How to execute an external program from within node.js. Commented Jun 5, 2021 at 8:28
  • sizeof(...) already returns an unsigned type (size_t), there's absolutely no need to cast to unsigned int. In worst case, you might even cut off size information (imagine 16-bit unsigned int and huge struct with more than 65k bytes). Admitted, that's rather of theoretical nature, but still the cast actually is not correct. Commented Jun 5, 2021 at 9:32

2 Answers 2

2

What you are looking for is the child_process module with the exec method

const { exec } = require('child_process');
const res = exec("./array", (error, stdout, stderr) => {
    // console.log({ error, stdout, stderr });
    const myResult = stdout.split(' ').map(e => parseFloat(e));
    console.log(myResult);
});

On the other hand, you need to output the value for node to handle it

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    double *arr;
    arr = (double *)calloc((3), (unsigned)(sizeof(double)));
    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;
    printf("%f %f %f", arr[0], arr[1], arr[2]);
    return 0;
}
Sign up to request clarification or add additional context in comments.

10 Comments

That is not enough: standard output has to be captured.
I'm just aswering this question here Is there a way to call that c program (array.out), the anwser on NodeJS side is child_process, if your question is can I trigger a function on my C program with NodeJS? the answer is yes, by handling arguments and passing that argument to the execSync command
It appears pretty obvious to me that user wants to retrieve information from the child process in the parent one: 'which returns a pointer to an array of doubles'. So a complete answer needs to cover that part as well.
@kapil-sarwat the only way I see is to run the program that dumps the result into a file and you read that new file. Other than that I don't see how else it could be done, but I'd gladly take any suggestion as I think this is a good question and I'm actually interested if there's another way
@kapilsarwat There are, but they aren't as simple: pipelines, sockets, shared memory, ... – data might even be passed as binary, but that's only valid if both C and python use the same representation for doubles (C uses host's representation which usually is IEEE 754, would assume the same for python, but not sure about!).
|
1

Not a full answer as solution is already given by savageGoat, but some additional hints on writing better C code:

double *arr;
arr = (double *)calloc((3), (unsigned)(sizeof(double)));

Please skip all those unnecessary parentheses, they just make the code harder to read. Assignment can occur directly with declaration, but that's rather a matter of personal preference:

double *arr = (double *)calloc(3, (unsigned)sizeof(double));

The cast to unsigned int is unnecessary, sizeof already evaluates to an unsigned type (size_t). Actually the cast even is technically wrong, as you might cut off size information that way: Imagine 16-bit unsigned int and a huge struct with more than 65k bytes – admitted, that's rather of theoretical nature, but still the cast is not correct.

Additionally you are assigning values afterwards anyway, so zero-initializing, which calloc does, is just unnecessary ballast, so prefer malloc in this case:

double *arr = (double *)malloc(3 * sizeof(double));

Now there's still a memory leak left! Sure, the OS will clean up that for you, as the process terminates anyway, but get used right from the start to considering to free any dynamically allocated memory right at the point of doing so (or even before...). Otherwise you will run into memory leaks on longer running processes.

Even better: Allocate the array on the stack, if not too large for; in this case, you even can initialize it right away:

double arr[] = { 10.0, 20.0, 30.0 }; // size is calculated by compiler

Finally, in this case you do not need the array at all:

printf("%f %f %f

Actually, you don't even need a dynamically allocated array at all:

printf("%f %f %f", 10.0, 20.0, 30.0);

Just make sure to use the correct literals (10, 20, 30 would provide three int values, which would be accepted as well by the compiler, but provoke undefined behaviour as not matching the required type for the format specifiers).

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.