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

你可能感兴趣的:(其它,javascript,c语言,开发语言)