如何从nodeJS调用C函数

mgdq6dx1  于 2023-08-04  发布在  Node.js
关注(0)|答案(3)|浏览(85)

我有一些C函数需要经常从nodeJS调用(时间间隔小于1秒)。C函数接受一个参数并返回一个值,该值可能是int或数组。
它可以像下面这样简单:

int main() {
    int x = 2;
    return x;
}

字符串
我需要在nodeJS中获取值x并能够执行console.log(x)
我试过使用node-ffi,但我从网上了解到它有很大的开销,因此对于频繁的函数调用来说效率很低。
我也考虑过写插件,但似乎很麻烦(用不熟悉的V8,C代码等等…)
关于nodeJS和C之间的集成也没有太多的资源(它们大多是nodeJS和C

有人能帮我解释一下吗?- 谢谢-谢谢

llycmphe

llycmphe1#

把你的c代码改成

// myProgram.c
#include <stdio.h>
int main(void){
    puts("4");
    return 0;
}

字符串
用gcc编译它,在与节点文件相同的目录中

$ gcc -o myProgram myProgram.c


在节点文件中,要求exec()

const { exec } = require("child_process");


并像这样使用它:

exec("./myProgram", (error, stdout, stderr) => console.log(stdout));


这很好用,它每次都会启动一个新的进程。
另一方面,如果你想保持子进程运行,并从node调用该代码中的函数,你可以这样做:

// 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;
}


编译multiplyBy2.c,然后:

// 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))

0wi1tuuw

0wi1tuuw2#

实现此目的的一种方法是使用node-gyp构建Node addon。Node友好地提供了a hello world addon demo,我们将在下面大致遵循它。
首先,您需要安装node-gyp。在进行初始设置时,请确保配置了兼容的Python版本。接下来你需要提供一个binding.gyp,这个文件告诉node-gyp如何构建你的项目。一个简单的binding.gyp可能看起来像这样:

{
  "targets": [
    {
      "target_name": "binding",
      "sources": [ "src/binding.cc" ]
    }
  ]
}

字符串
准系统绑定可能如下所示。虽然它是用C编写的,但您可以以大致相同的方式集成C代码。请参阅this article,了解如何混合使用C和C

#include <node.h>
#include <v8.h>

void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
  v8::Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "hello world").ToLocalChecked());
}

void init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {
  NODE_SET_METHOD(exports, "foo", Method);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, init);


接下来,您可以运行node-gyp configure来让node-gyp设置构建工具,然后运行node-gyp build来让它构建您的插件。如果输出以gyp info ok结尾,那么您已经成功构建了第一个本机插件。
您可以将绑定作为任何旧模块导入并在Node中使用:

const binding = require("./build/Release/binding");

console.log(binding.foo()); // Will log "hello world"

vm0i2vca

vm0i2vca3#

使用子进程。,... https://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback

相关问题