zoukankan      html  css  js  c++  java
  • nodejs与c语言交互应用实例

    nodejs与c/c++交互目前主流的方式有两种,node addon c++ 和 node-ffi .

    1、node addon c++

    1)nodejs从c语言读取数据

    addon.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    typedef struct
    {
        double lon;
        double lat;
    }gps_info_t;
    
    gps_info_t* gps;
    
    
    void get_gps_shm_init(void)
    {
        gps = (gps_info_t *)malloc(sizeof(gps_info_t));
    }
    
    Napi::Object CreateObject(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        Napi::Object obj = Napi::Object::New(env);
        
        gps->lon = 55.5;
        gps->lat = 66.6;
    
        printf("send lon: %f
    ", gps->lon);
        printf("send lat: %f
    ", gps->lat);
    
          obj.Set(Napi::String::New(env, "lon"), gps->lon);
        obj.Set(Napi::String::New(env, "lat"), gps->lat);
    
          return obj;
    }
    
    Napi::Object Init(Napi::Env env, Napi::Object exports) {
        get_gps_shm_init();
          return Napi::Function::New(env, CreateObject, "createObject");
    }
    
    NODE_API_MODULE(addon, Init)

    addon.js

    var addon = require('bindings')('addon');
    
    var obj = addon('gps');
    
    console.log(obj.lon);
    console.log(obj.lat);
    
    module.exports.obj = obj;

    2)nodejs向c语言写数据

    addon.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    typedef struct
    {
        char *user_name;
        char *passwd;
        char *dev_id;
    }user_info_t;
    
    user_info_t* user;
    
    void put_user_info_shm_init(void)
    {
        user = (user_info_t *)malloc(sizeof(user_info_t));
        user->user_name = (char*)malloc(32*sizeof(char));
        user->passwd = (char*)malloc(32*sizeof(char));
        user->dev_id = (char*)malloc(32*sizeof(char));
    }
    
    Napi::Object CreateObject(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
        Napi::Object obj = Napi::Object::New(env);
    
        memset(user->user_name, 0, 32); 
        memset(user->passwd, 0, 32); 
        memset(user->dev_id, 0, 32); 
        memcpy(user->user_name, info[0].ToString(), 32);
        memcpy(user->passwd, info[1].ToString(), 32);
        memcpy(user->dev_id, info[2].ToString(), 32);
    
        printf("recv user info (user_name): %s
    ", user->user_name);
        printf("recv user info (passwd): %s
    ", user->passwd);
        printf("recv user info (dev_id): %s
    ", user->dev_id);    
    
          return obj;
    }
    
    Napi::Object Init(Napi::Env env, Napi::Object exports) {
        put_user_info_shm_init();
          return Napi::Function::New(env, CreateObject, "createObject");
    }
    
    NODE_API_MODULE(addon, Init)

    addon.js

    var addon = require('bindings')('addon');
    
    var user_info = {
        user_name = 'zdd';
        passwd = '123';
        dev_id = '65535'
    }
    
    var obj = addon(user_info.user_name,user_info.passwd,user_info.dev_id);
    
    module.exports.user_info = user_info;

    nodejs的C/C++拓展,将c/c++源码编译成js模板库

    ubuntu下编译

    node-gyp configure
    node-gyp build

    node addon.js

    交叉编译
    export CC=arm-linux-gnueabihf-gcc
    export CXX=arm-linux-gnueabihf-g++
    export LD=arm-linux-gnueabihf-ld
    export RAINLIB=arm-linux-gnueabihf-rainlib
    export AR=arm-linux-gnueabihf-ar
    export LINK=arm-linux-gnueabihf-g++
    node-gyp configure --arch=arm
    node-gyp build

    node addon.js

    2、node-ffi

    1)nodejs从c语言读取数据

    factorial.c

    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    
    #if defined(WIN32) || defined(_WIN32)
    #define EXPORT __declspec(dllexport)
    #else
    #define EXPORT
    #endif
    
    typedef struct
    {
        double lon;
        double lat;
    }gps_info_t;
    
    gps_info_t* gps;
    
    void get_gps_shm_init(void)
    {
        gps = (gps_info_t *)malloc(sizeof(gps_info_t));
    }
    
    EXPORT gps_info_t* get_gps_info(void) {
      get_gps_shm_init();
      gps->lon = 55.5;
      gps->lat = 55.5;return gps;
    }

    factorial.js

    var ffi = require('../node-ffi-master/')
    var refStruct = require('ref-struct');
    var refArray = require('ref-array');
    var ref = require('ref');
    
    //gps date struct
    var gps = refStruct({
        'lon':ref.types.double,
        'lat':ref.types.double,
    });
    
    var gpsStructArrayType = refArray(gps);
    var gps_info = gpsStructArrayType(10);
    
    var libfactorial = ffi.Library('./libfactorial', {
      'get_gps_info': [ gpsStructArrayType, [ 'void' ] ],
    });
    
    gps_info = libfactorial.get_gps_info(0)
    
    console.log('Your output: ' + gps_info[0].lon)
    console.log('Your output: ' + gps_info[0].lat)
    

    2)nodejs向c语言写数据

    factorial.c

    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    
    #if defined(WIN32) || defined(_WIN32)
    #define EXPORT __declspec(dllexport)
    #else
    #define EXPORT
    #endif
    
    typedef struct
    {
        char *user_name;
        char *passwd;
        char *dev_id;
    }user_info_t;
    
    user_info_t* user;
    
    void put_user_info_shm_init(void)
    {
        user = (user_info_t *)malloc(sizeof(user_info_t));
        user->user_name = (char*)malloc(32*sizeof(char));
        user->passwd = (char*)malloc(32*sizeof(char));
        user->dev_id = (char*)malloc(32*sizeof(char));
    }
    
    EXPORT void put_user_info(user_info_t* user_info) {
      put_user_info_shm_init();
      printf("get userinfo(user_name):%s",user_info->user_name);
      printf("get userinfo(user_name):%s",user_info->passwd);
      printf("get userinfo(user_name):%s",user_info->dev_id);
    }

     factorial.js

    var ffi = require('../node-ffi-master/')
    var refStruct = require('ref-struct');
    var refArray = require('ref-array');
    var ref = require('ref');
    
    //ui date struct
    var user = refStruct({
        'user_name':'string',
        'passwd':'string',
        'dev_id':'string',
    });
    
    var userStructArrayType = refArray(user);
    var user_info = userStructArrayType(1);
    
    user_info[0].user_name = 'zdd';
    user_info[0].passwd = '123';
    user_info[0].dev_id = '65535';
    
    var libfactorial = ffi.Library('./libfactorial', {
      'put_user_info': [ 'void', [ userStructArrayType ] ]
    });
    
    libfactorial.put_user_info(user_info)
    
    console.log('Your input: ' + user_info[0].user_name)
    console.log('Your input: ' + user_info[0].passwd)
    console.log('Your input: ' + user_info[0].dev_id)

    gcc / arm-linux-gnueabihf-gcc -shared -fpic factorial.c -o libfactorial.so

    node factorial.js

    上面两种方式写了个demo放在github上了

    https://github.com/zhoudd1/nodejs_call_c_cc

    3、还有一种小众化的方式

    通过child_process 方式调用EXE进程来实现数据交互。

    var cp= require('child_process');
    //同步的方式

    letout = cp.execFileSync("testdll.exe", ["arg1","arg2"],{});


    //异步的方式

    cp.execFile("testdll.exe", ["arg1","arg2"], {}, (error, stdout, stderr) => {
        console.log(stdout);
    })
     

    这种方式NODE 会接管stdout 和 stderr ,exe中把结果通过 printf 输出。
    缺点:需要先生成EXE,EXE 中调用 DLL/so 并且返回结果。
    优点:不需要配置 FFI,不受DLL/so 的影响

    更多细节

     https://www.cnblogs.com/chyingp/p/node-learning-guide-child_process.html

     https://blog.csdn.net/zeping891103/article/details/52230175

  • 相关阅读:
    tar命令解压jdk.tar.gz包 报错 gzip: stdin: not in gzip format
    CentOS6.5安装完没有网络的解决办法
    UML在需求分析阶段的应用
    UML
    UML在软件开发中各个阶段的作用和意义
    Maven那点事儿(Eclipse版)
    eclipse和myeclipse的下载地址
    div的作用
    c:if标签数据回显判断是否选中
    《Hadoop》对于高级编程Hadoop实现构建企业级安全解决方案
  • 原文地址:https://www.cnblogs.com/dong1/p/8890892.html
Copyright © 2011-2022 走看看