用electron做一个访问can卡的上位机

使用node-ffi-napi 访问dll文件,需要安装
ffi-napi
ref-napi
ref-array-napi
ref-struct-napi

安装ffi需要用到node-gyp,安装教程可以百度下

以下是使用过程


需要调用的dll的.h头文件如下,此dll是用来访问can卡的

#ifndef CONTROLCAN_H
#define CONTROLCAN_H//#include <cvidef.h> //使用CVI平台开发,请使用该语句。
//接口卡类型定义
#define VCI_USBCAN1     3
#define VCI_USBCAN2     4
#define VCI_USBCAN2A        4
#define VCI_USBCAN_E_U      20
#define VCI_USBCAN_2E_U     21//函数调用返回状态值
#define STATUS_OK                   1
#define STATUS_ERR                  0
//1.ZLGCAN系列接口卡信息的数据类型。
typedef  struct  _VCI_BOARD_INFO{   USHORT  hw_Version;USHORT   fw_Version;USHORT   dr_Version;USHORT   in_Version;USHORT   irq_Num;BYTE    can_Num;CHAR    str_Serial_Num[20];CHAR str_hw_Type[40];USHORT  Reserved[4];
} VCI_BOARD_INFO,*PVCI_BOARD_INFO;
//2.定义CAN信息帧的数据类型。
typedef  struct  _VCI_CAN_OBJ{UINT  ID;UINT TimeStamp;BYTE  TimeFlag;BYTE   SendType;BYTE   RemoteFlag;//是否是远程帧BYTE ExternFlag;//是否是扩展帧BYTE DataLen;BYTE    Data[8];BYTE    Reserved[3];
}VCI_CAN_OBJ,*PVCI_CAN_OBJ;
//3.定义初始化CAN的数据类型
typedef struct _VCI_INIT_CONFIG{DWORD   AccCode;DWORD   AccMask;DWORD   Reserved;UCHAR  Filter;UCHAR    Timing0;    UCHAR   Timing1;    UCHAR   Mode;
}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;
/ new add struct for filter /
typedef struct _VCI_FILTER_RECORD{DWORD ExtFrame;   //是否为扩展帧DWORD Start;DWORD End;
}VCI_FILTER_RECORD,*PVCI_FILTER_RECORD;#define EXTERNC      extern "C"
EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved);
EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd);
EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);
EXTERNC DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo);
EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);
EXTERNC ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
EXTERNC DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
EXTERNC DWORD __stdcall VCI_StartCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
EXTERNC DWORD __stdcall VCI_ResetCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
EXTERNC ULONG __stdcall VCI_Transmit(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,ULONG Len);
EXTERNC ULONG __stdcall VCI_Receive(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime);
/*------------------------------------------------其他补充函数及数据结构描述------------------------------------------------*/
//USB-CAN总线适配器板卡信息的数据类型1,该类型为VCI_FindUsbDevice函数的返回参数。
typedef  struct  _VCI_BOARD_INFO1{USHORT    hw_Version;USHORT   fw_Version;USHORT   dr_Version;USHORT   in_Version;USHORT   irq_Num;BYTE    can_Num;BYTE    Reserved;CHAR   str_Serial_Num[8];CHAR  str_hw_Type[16];CHAR    str_Usb_Serial[4][4];
} VCI_BOARD_INFO1,*PVCI_BOARD_INFO1;
//USB-CAN总线适配器板卡信息的数据类型2,该类型为VCI_FindUsbDevice函数的返回参数。为扩展更多的设备
typedef  struct  _VCI_BOARD_INFO2{USHORT    hw_Version;USHORT   fw_Version;USHORT   dr_Version;USHORT   in_Version;USHORT   irq_Num;BYTE    can_Num;BYTE    Reserved;CHAR   str_Serial_Num[8];CHAR  str_hw_Type[16];CHAR    str_Usb_Serial[10][4];
} VCI_BOARD_INFO2,*PVCI_BOARD_INFO2;#define EXTERNC     extern "C"
EXTERNC DWORD __stdcall VCI_GetReference2(DWORD DevType,DWORD DevIndex,DWORD CANIndex,DWORD Reserved,BYTE *pData);
EXTERNC DWORD __stdcall VCI_SetReference2(DWORD DevType,DWORD DevIndex,DWORD CANIndex,DWORD RefType,BYTE *pData);
EXTERNC DWORD __stdcall VCI_ConnectDevice(DWORD DevType,DWORD DevIndex);
EXTERNC DWORD __stdcall VCI_UsbDeviceReset(DWORD DevType,DWORD DevIndex,DWORD Reserved);
EXTERNC DWORD __stdcall VCI_FindUsbDevice(PVCI_BOARD_INFO1 pInfo);
EXTERNC DWORD __stdcall VCI_FindUsbDevice2(PVCI_BOARD_INFO2 pInfo);
#endif

nodejs中安装完成下列包

  "dependencies": {"ffi-napi": "^3.1.0","ref-array-napi": "^1.2.1","ref-napi": "^3.0.1","ref-struct-napi": "^1.1.1"}

然后在js文件中使用 (注释和解释在代码中)

dll 的调用需要注意dll是64位还是32位的
这里nodejs是64位的,dll也是64位的
否则可能报错

let ffi = require("ffi-napi");
let ref = require('ref-napi');
let ArrayType = require('ref-array-napi');
let StructType = require('ref-struct-napi');let _VCI_BOARD_INFO = StructType({    //定义结构体hw_Version: ref.types.ushort,fw_Version: ref.types.ushort,dr_Version: ref.types.ushort,in_Version: ref.types.ushort,irq_Num: ref.types.ushort,can_Num: ref.types.byte,str_Serial_Num: ArrayType(ref.types.char, 20),    //char str_Serial_Num[20]str_hw_Type: ArrayType(ref.types.char, 40),Reserved: ArrayType(ref.types.ushort, 4),
})
let _VCI_CAN_OBJ = StructType({  //定义结构体ID: ref.types.uint,TimeStamp: ref.types.uint,TimeFlag: ref.types.byte,SendType: ref.types.byte,RemoteFlag: ref.types.byte,ExternFlag: ref.types.byte,DataLen: ref.types.byte,Data: ArrayType(ref.types.byte, 8),Reserved: ArrayType(ref.types.byte, 3),
})let _VCI_INIT_CONFIG = StructType({  //定义结构体AccCode: ref.types.ulong,        //DWORD 就是 ref.types.ulongAccMask: ref.types.ulong,Reserved: ref.types.ulong,Filter: ref.types.uchar,Timing0: ref.types.uchar,Timing1: ref.types.uchar,Mode: ref.types.uchar,
})
let _VCI_FILTER_RECORD = StructType({  //定义结构体ExtFrame: ref.types.ulong,Start: ref.types.ulong,End: ref.types.ulong,
})
let _VCI_BOARD_INFO1 = StructType({  //定义结构体hw_Version: ref.types.ushort,fw_Version: ref.types.ushort,dr_Version: ref.types.ushort,in_Version: ref.types.ushort,irq_Num: ref.types.ushort,can_Num: ref.types.byte,Reserved: ref.types.byte,str_Serial_Num: ArrayType(ref.types.char, 8),str_hw_Type: ArrayType(ref.types.char, 16),str_Usb_Serial: ArrayType(ArrayType(ref.types.char, 4), 4), //char str_Usb_Serial[4][4]
})
let _VCI_BOARD_INFO2 = StructType({   //定义结构体hw_Version: ref.types.ushort,fw_Version: ref.types.ushort,dr_Version: ref.types.ushort,in_Version: ref.types.ushort,irq_Num: ref.types.ushort,can_Num: ref.types.byte,Reserved: ref.types.byte,str_Serial_Num: ArrayType(ref.types.char, 8),str_hw_Type: ArrayType(ref.types.char, 16),str_Usb_Serial: ArrayType(ArrayType(ref.types.char, 10), 4),   //char str_Usb_Serial[10][4]
})
let canDLL = ffi.Library('./ControlCAN.dll', {   //定义方法'VCI_OpenDevice': [ref.types.ulong, [ref.types.ulong, ref.types.ulong, ref.types.ulong]],'VCI_CloseDevice': [ref.types.ulong, [ref.types.ulong, ref.types.ulong]],'VCI_StartCAN': [ref.types.ulong, [ref.types.ulong, ref.types.ulong, ref.types.ulong]],'VCI_ReadBoardInfo': [ref.types.ulong, [ref.types.ulong, ref.types.ulong, ref.refType(_VCI_BOARD_INFO)]],'VCI_InitCAN': [ref.types.ulong, [ref.types.ulong, ref.types.ulong, ref.types.ulong, ref.refType(_VCI_INIT_CONFIG)]],'VCI_FindUsbDevice': [ref.types.ulong, [ref.refType(_VCI_BOARD_INFO1)]]
})//打开设备
let open = canDLL.VCI_OpenDevice(3, 0, 0)  //传入3个DWORD
console.log(open)
//设备初始化
let initconfig = new _VCI_INIT_CONFIG({  //创建一个结构体并赋值AccCode: 0x80000008,AccCode: 0xFFFFFFFF,Filter: 0,Timing0: 0x03,Timing1: 0x1c,Mode: 0
});
let init = canDLL.VCI_InitCAN(3, 0, 0, initconfig.ref())  //传入3个dword和一个结构体指针
console.log(init)//打开can
let startCan = canDLL.VCI_StartCAN(3, 0, 0);
console.log(startCan)
//打印接口卡信息
let boardinfo = new _VCI_BOARD_INFO();   //创建一个结构体
canDLL.VCI_ReadBoardInfo.async(3, 0, boardinfo.ref(), (err, result) => {if (err) {console.log(err)}console.log(result)  //调用成功后,返回1console.log("--------------接口卡信息------------------------")console.log('hw_Version:'+boardinfo.hw_Version)   //访问结构体内的值console.log('fw_Version:'+boardinfo.fw_Version) console.log('dr_Version:'+boardinfo.dr_Version)console.log('in_Version:'+boardinfo.in_Version)console.log('irq_Num:'+boardinfo.irq_Num)console.log('can_Num:'+boardinfo.can_Num)console.log(boardinfo.str_Serial_Num)console.log(boardinfo.str_hw_Type)console.log(boardinfo.Reserved)
})

nodejs使用node-ffi-napi 访问dll文件相关推荐

  1. Linux 创建网页服务,Linux使用Node.js建立访问静态网页的服务实例详解

    Linux使用Node.js建立访问静态网页的服务实例详解 一.安装node.js运行所需要的环境,: 二.创建node目录(/node/www),并在目录下创建node.js服务文件server.j ...

  2. nodejs安装ffi模块调用dll详解

    网上很多关于nodejs安装ffi的模块讲的条理实在太不清晰了,nodejs使用的VC++运行库对于不同的nodejs版本是不一致的.nodejs10需要的vs版本是vs2015. 1 安装vs201 ...

  3. ASP.NET2.0关于BIN目录下DLL文件访问的问题

    自己做一个访问自定义配置文件的类,生成DLL文件,放入网站的BIN目录下. 配置文件与DLL文件在同一目录下,DLL文件通过获取当前加载的模块的地址,来获得配置文件的地址.简单代码如下: 1strin ...

  4. C# Modbus TCP协议客户端设计工程源码带注释,开源 dll文件,支持访问多个服务器,多线程实现,西门子C# Simens PPI Master

    西门子C# Simens PPI Master C# Modbus TCP协议客户端设计工程源码带注释,开源 dll文件,支持访问多个服务器,多线程实现 renfengli2010

  5. node+express使用multiparty实现文件上传

    欢迎点击「算法与编程之美」↑关注我们! 本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 作者|王小强 来源|https://my.oschina.ne ...

  6. lib和dll文件的区别和联系

    什么是lib文件,lib和dll的关系如何 (2008-04-18 19:44:37)      (1)lib是编译时需要的,dll是运行时需要的.  如果要完成源代码的编译,有lib就够了.  如果 ...

  7. 如何在全局程序集缓存 (GAC) 中安装 DLL 文件

    要使用 Visual Studio .NET 创建小型类库项目.生成强名称,以及在 GAC 中安装项目的 .dll 文件,请执行下列步骤: 在 Visual Studio .NET 中,创建一个新 V ...

  8. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑

    自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问题.相信有很多人并不是很清楚32位程序与64位程序的区别,以及Program Files (x86),Program Files的区别 ...

  9. java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...

  10. SQL Server Compact的DLL文件介绍

    SQL Server Compact是一种In-Process数据库引擎,它由多个DLL文件构成,下面就以SQL Server Compact 3.5为例子简单介绍一下每个DLL文件的作用. sqlc ...

最新文章

  1. 新报告直指3大安全威胁 企业需小心应对
  2. cnblogs_504 Gateway Time-out
  3. react 数字转字符_深入浅出 React -- JSX
  4. 前端学习(2308):react之子传父
  5. 服务器文件忽略大小写,服务器文件忽略大小写
  6. 获取所有汉字与 Unicode 的对照表
  7. 最新VmWare14激活序列号
  8. Linux源码安装Mysql5.7
  9. centos7镜像文件
  10. 没有一个绝对安全的系统 (二) 破解路由器后台密码
  11. 电源防反接和防倒灌 - 使用MOS 管和运放实现理想二极管
  12. C#如何在Windows上接入蓝牙设备
  13. 怎么把jpg转换成pdf方法
  14. php球半径为2的圆面积,某竖直平面内有一半径为R的光滑固定圆环,斜边长2R、短边长R的匀质直角三角板放在环内,试求三角板在其平衡位...
  15. [转]平凡是福,金玉满堂,莫之能守。富贵而骄,自遗其咎。
  16. Python3,5句话实现自动接收短信提醒
  17. Python 小写数字转为大写
  18. 数智经济转型下如何抢占文创发展新机遇?中国移动咪咕聚焦新一代年轻人需求
  19. java随机生成人名
  20. 第一课:Python变量

热门文章

  1. Dubbo Failover机制
  2. 【c语言】判断一个数n能否同时被3和5整除
  3. bzoj4987 Tree [树形背包]
  4. uvalive 4987 Evacuation Plan 疏散计划
  5. 将一个CSV格式的文件分割成两个CSV文件
  6. error: Apostrophe not preceded by \ (in XXX.)
  7. vue+echarts+springboot实现云词图
  8. 持续学习:(Elastic Weight Consolidation, EWC)Overcoming Catastrophic Forgetting in Neural Network
  9. 前端---HTML制作百度首页
  10. vivo双卡流量切换流程