JavaScript调用C库

本文介绍通过ffi方式调用C动态库
系统:ubuntu16.04 64bit

一、环境安装
  1. 安装js运行环境

    • V17.3.0 地址:https://nodejs.org/dist
    • wget https://nodejs.org/dist/v17.6.0/node-v17.6.0-linux-x64.tar.xz
    • 解压tar xvf node-v17.6.0-linux-x64.tar.xz
    • sudo mv node-v17.6.0-linux-x64 /usr/local/nodejs
    • 添加环境变量 vi ~/.bashrc (添加后重启终端窗口)
      export PATH=$PATH:/usr/local/nodejs/bin
      export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/nodejs/lib
      
  2. 安装ffi相关

    • 设置源:npm config set registry https://registry.npmmirror.com (淘宝)
    • npm config set python /usr/bin/python3 (python>3.6.0)
    • npm install node-gyp
    • npm install ffi-napi
    • npm install ref-napi
    • npm install ref-array-napi
    • npm install ref-struct-napi
二、测试代码
  1. c代码test.c–>编译出动态库libtest.so

    #include <stdio.h>
    typedef struct {
        int id;
        char* name;
        double height;
        int score[10];
        int score_size;
    }userStruct;
    typedef void (*callback)(int val);
    static char char_point[64] = "";
    int api_int(int a, int b) {
        return a + b;
    }
    
    double api_double(double a, double b) {
        return a + b;
    }
    
    char* api_char_point(char* a, char* b){
        memset(char_point, 0, sizeof(char_point));
        sprintf(char_point, "%s %s", a, b);
        return char_point;
    }
    
    int api_int_array(int* a, int size){
        int i = 0; 
        for(i = 0; i < size; i++){
            a[i] = i;
        }
        return 0;
    }
    
    int api_struct(userStruct user){
        int i = 0;
        char buf[128] = "";
        printf("C Print score_size:%d\n", user.score_size);
        for(i = 0; i < user.score_size; i++){
            printf("C Print i:%d, score:%d\n",i, user.score[i]);
            sprintf(buf, "%s %d", buf, user.score[i]);
        }
        printf("C Print id:%d name:%s height:%f socre:%s\n", user.id, user.name, user.height, buf);
        return 0;
    }
    void api_callback(callback cb){
        cb(1);
    }
    
    
  2. js代码 test.js

    const ffi = require('ffi-napi');
    const ref = require('ref-napi');
    const refArray = require('ref-array-napi')
    const StructType = require('ref-struct-napi');
    const IntArray10 = refArray(ref.types.int, 10);
    const userStruct = StructType({
        id: 'int',
        name: 'string',
        height: 'double',
        score: IntArray10,
        score_size: 'int'
    });
    
    const rockeyInterface = {
        'api_int':['int', ['int', 'int']],
        'api_double':['double', ['double', 'double']],
        'api_char_point':['string', ['string', 'string']],
        'api_int_array':['int', ['pointer', 'int']],
        'api_struct':['int', [userStruct]],
        'api_callback':['void', ['pointer']]
    }
    
    let libtest = new ffi.Library('./libtest.so', rockeyInterface);
    //int test
    console.log("int result:", libtest.api_int(1, 2));
    //double test
    console.log("double Result:", libtest.api_double(1.1, 1.2));
    //char* test
    console.log("char* result:", libtest.api_char_point('hello', 'world'));
    //int array test
    let arraySize = 10;
    let arrayBuf = Buffer.alloc(arraySize* Int32Array.BYTES_PER_ELEMENT);
    console.log(typeof arrayBuf);
    console.log(arrayBuf.length);
    if(libtest.api_int_array(arrayBuf, arraySize) == 0){
        let arrayResult = new Int32Array(arrayBuf.buffer);
        console.log("int array result:", arrayResult);
    }
    //struct test
    let user = new userStruct();
    user.id = 101;
    user.name = 'hsl';
    user.height = 1.78;
    user.score_size = 10;
    user.score = new IntArray10();
    for(var i = 0; i < user.score_size; i++){
        user.score[i] = i+1;
    }
    let ret = libtest.api_struct(user);
    console.log("struct result:", ret);
    
    //callback test
    const callback = ffi.Callback('int', ['int'], function(value){
        console.log("callback result:", value);
    });
    libtest.api_callback(callback);
    
  3. 运行:node test.js

附:

python3升级
	下载:wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tgz
	tar xvf Python-3.7.9.tgz
	cd Python-3.7.9
	./configure
	make && sudo make install
	sudo rm /usr/bin/python3
	sudo ln -s /usr/local/bin/python3 /usr/bin/python3
  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js可以使用`ffi`模块调用设备驱动的dll动态库。`ffi`模块 stands for `Foreign Function Interface`(外部函数接口),它允许Node.js应用程序直接调用动态链接中的C/C++函数。 使用`ffi`模块调用设备驱动的dll动态库,首先需要安装`ffi`模块。可以使用npm(Node.js的包管理器)通过以下命令进行安装: ```shell npm install ffi ``` 安装完成后,可以在Node.js应用程序中使用`ffi`模块调用设备驱动的dll动态库。首先需要引入`ffi`模块: ```javascript const ffi = require('ffi'); ``` 然后,使用`ffi.Library`方法加载dll动态库,并定义要调用的函数: ```javascript const libraryPath = 'path/to/your/device/driver.dll'; const myLibrary = ffi.Library(libraryPath, { 'functionName1': ['returnType1', ['parameterType1', 'parameterType2']], 'functionName2': ['returnType2', ['parameterType3', 'parameterType4']] }); ``` 在上述代码中,`functionName1`和`functionName2`是设备驱动DLL中的函数名,`returnType1`和`returnType2`是函数的返回值类型,`parameterType1`、`parameterType2`、`parameterType3`和`parameterType4`是参数的类型。 接下来,可以通过调用`myLibrary`对象的方法来调用设备驱动DLL中的函数: ```javascript myLibrary.functionName1(parameter1, parameter2); ``` 其中,`parameter1`和`parameter2`是要传递给设备驱动DLL函数的参数。 通过以上步骤,就可以在Node.js应用程序中调用设备驱动的dll动态库了。当然,在调用之前,需要确保设备驱动dll动态库的路径正确,以及设备驱动dll动态库中的函数名、参数类型和返回值类型的定义正确。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值