一文学会搭建HTTP服务器调用DLL库

 更新时间:2023年06月25日 09:17:31   作者:轩  
这篇文章主要为大家介绍了一文学会搭建HTTP服务器调用DLL库,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

如何搭建HTTP服务器调用DLL库

之前在帮朋友救急时,忽然想到了这个方法,就是通过HTTP服务器调用DLL库。在某些情况下,我们可能需要远程调用本地的 DLL 库。为了实现这个目标,我们可以搭建一个 HTTP 服务器,通过发送 HTTP 请求来调用 DLL 库的函数。这种方法可以让我们在不将 DLL 库放到远程机器上的情况下,实现对 DLL 函数的远程调用。

环境:MacOS + Node 18.0.0
目的:酒店的房卡系统,通过HTTP服务器调用DLL库,实现对房卡的读取、写入、删除等操作。

准备阶段

  • 安装 Node.js:首先,我们需要安装 Node.js。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它可以帮助我们构建高效的网络应用程序。
  • 创建 HTTP 服务器:使用 Node.js 的内置模块,我们可以轻松地创建一个简单的 HTTP 服务器。我们将展示如何编写一个简单的 Node.js 脚本,以创建一个监听特定端口的 HTTP 服务器。这里我们使用express框架。
  • 调用 DLL 库:为了调用 DLL 库,我们将使用 Node.js 的 "ffi" 模块。该模块允许我们加载和调用动态链接库(DLL)中的函数。我们将演示如何使用 "ffi" 模块加载 DLL 库,并调用其中的函数。

搭建基础读取DLL库

首先创建一个文件夹:mkdir http-dll,然后进入该文件夹:cd http-dll

1.1 创建 package.json 文件

在该文件夹下创建 package.json 文件:pnpm init -y

1.2 安装依赖

安装依赖:pnpm i ffi ref-struct ref-array ref

1.3 读取

搭建的过程不重要,为什么用的原因更重要,其次是思考怎么处理,最后是设计使用的方法。

假如这里我们使用的是LockSDK.dll,这里只是为了演示,提供了基础的4个方法,因此以这4个方法为例子。

  • TP_Configuration:动态库初始化配置,完成门锁类型选择/发卡器连接等
  • TP_MakeGuestCardEx: 制作宾客卡
  • TP_ReadGuestCardEx: 读宾客卡信息
  • TP_CancelCard: 注销卡片/卡片回收

此处不展示具体的C代码,而直接以DLL库的形式提供给我们使用。

首先要考虑一个问题,单纯从文档里拿去使用和调用的话,会出现什么问题?

  • 每次使用都需要读文档
  • 每次使用都需要重新编写代码
  • 没有统一的调用方法,很容易出现凌乱的管理

那我们需要在此设置一个目标,就是将这些方法封装起来,统一调用,方便管理。而我们创建一个conf目录,用于存放配置文件,创建dll.conf.js文件,用于存放dll配置信息。

/**
函数名:TP_Configuration
功能:动态库初始化配置,完成门锁类型选择/发卡器连接等
@param {number} lock_type - 门锁类型(也就是使用的卡片类型): 4-RF57门锁; 5-RF50门锁
@returns {number} - 错误类型
注意:此函数为 __stdcall 调用约定,如果您的函数库采用的是 __cdecl 调用约定,需要将其修改为 __stdcall 调用约定。
*/
export const TP_Configuration = {
  "TP_Configuration": [
    "int", // return
    // parameters
    ["int"],
  ],
};
  • 这种配置方法是为了方便ffi调用,暂且不表。

如果只是这种方式配置,那么我们还是需要每次都去读文件,然后重新编写,这样就没有意义了。因此我们需要考虑一个更方便的方式,也就是放置在一个统一的文件内,通过调用这个文件,来获取我们需要的所有方法。

因此创建conf.js文件,用于存放所有的方法。

const { TP_Configuration, TP_MakeGuestCardEx, TP_ReadGuestCardEx, TP_CancelCard } = require('./dll.conf.js')
export const LIB_NAME = "../dll/mylib.dll"
export const lib_func = {
    TP_Configuration,
    TP_MakeGuestCardEx,
    TP_ReadGuestCardEx,
    TP_CancelCard
}
module.exports = {
    LIB_NAME,
    lib_func
}

此时我们已经配置好了conf的配置文件,那么下一步,我们就需要实现读取和调用的方法。

我们创建一个core目录,用于存放核心方法,创建load.js文件,用于存放核心方法。

const { lib_func, LIB_NAME } = require('../conf/conf.js')
const ffi = require('ffi');
const ref = require('ref');
const {
    TP_Configuration,
    TP_MakeGuestCardEx,
    TP_ReadGuestCardEx,
    TP_CancelCard
} = ffi.Library(LIB_NAME, lib_func);
module.exports = {
    TP_Configuration,
    TP_MakeGuestCardEx,
    TP_ReadGuestCardEx,
    TP_CancelCard
}
  • ffi模块,用于加载和调用动态链接库(DLL)中的函数。
  • ref模块,用于处理C语言中的指针问题。
  • 这里我们将Library从DLL里读取出来的函数,放置在一个对象里,方便外部调用。此处我们让HTTP服务器来调用

1.4 创建HTTP服务器

安装express框架,然后在创建server目录,用于存放HTTP服务器。

server目录下创建app.js文件,用于存放HTTP服务器。

const express = require('express');
class App {
    routes;
    app = express();
    constructor(routes) {
        this.routes = routes;
        this.requestEntry()
    }
    requestEntry() {
        this.routes.forEach(route => {
            this.app[route.method](route.path, route.handler)
        })
    }
    listen(port) {
        app.listen(port, () => {
            console.log(`Example app listening at http://localhost:${port}`)
        })
    }
}
module.exports = {
    App
}
  • 此处我们将HTTP服务器的创建和路由的配置分离,方便管理。

下面我们创建目录文件routes.js,用于存放路由配置。

const CancelController = require('./controller/cancel.controller.js')
const ConfigurationController = require('./controller/configuration.controller.js')
const MakeGuestCardEx = require('./controller/MakeGuestCardEx.controller')
const ReadGuestCardExController = require('./controller/ReadGuestCardExController.controller')
const routes = [
    {
        path: '/cancel',
        method: 'post',
        handler: new CancelController(),
    },
    {
        path: '/configuration',
        method: 'post',
        handler: new ConfigurationController(),
    },
    {
        path: '/make-guest-card-ex',
        method: 'post',
        handler: new MakeGuestCardEx(),
    },
    {
        path: '/read-guest-card-ex',
        method: 'post',
        handler: new ReadGuestCardExController(),
    }
]
module.exports = {
    routes
}

在逻辑上,我们需要把每个路由的处理逻辑分离出来,因此我们创建controller目录,用于存放路由处理逻辑。

controller目录下创建cancel.controller.js文件,用于存放路由处理逻辑。

const ref = require("ref");
const { TP_CancelCard } = require("../../core/load");
class CancelController {
  constructor() {}
  async handler(_req, res) {
    try {
      const card_snr = _req.body.card_snr || ref.allocCString("", 20);
      const result = await TP_CancelCard(card_snr);
      const card_snr_str = ref.readCString(card_snr);
      return res.status(201).send({
        data: {
          result,
          card_snr_str,
        },
      });
    } catch (error) {
      res.status(500).json(error);
    }
  }
}
module.exports = CancelController
  • 到这个时候,我们已经完成了对DLL的函数的一个完整的调用,并且把这个调用封装成了一个HTTP服务器,方便我们通过网页端来进行处理。

此外,我们还需要一个main.js文件,用于启动HTTP服务器。

const App = require('./server/app.js')
const { routes } = require('./server/routes.js')
const app = new App(routes);
app.listen(3000)

到这一步,整体流程就走完了。我们只需要在终端中输入node main.js,就可以启动HTTP服务器了。

最终结果

目录结构如下:

.
├── conf
│   ├── conf.js
│   └── dll.conf.js
├── core
│   └── load.js
├── dll
│   └── LockSDK.dll
├── main.js
├── mock
│   └── mockUse.js
├── package.json
├── pnpm-lock.yaml
└── server
    ├── app.js
    ├── controller
    │   ├── cancel.controller.js
    │   ├── configuration.controller.js
    │   ├── makeGuestCardEx.js
    │   └── readGuestCardEx.controller.js
    └── routes.js

Reference Node-DLL

以上就是一文学会搭建HTTP服务器调用DLL库的详细内容,更多关于HTTP服务器调用DLL库搭建的资料请关注脚本之家其它相关文章!

相关文章

  • 浅析node中间件及实现一个简单的node中间件

    浅析node中间件及实现一个简单的node中间件

    这篇文章主要介绍了浅析node中间件及实现一个简单的node中间件,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • yarn 命令死循环问题分析解决

    yarn 命令死循环问题分析解决

    这篇文章主要为大家介绍了yarn 命令死循环问题分析解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • koa2服务配置SSL的实现方法

    koa2服务配置SSL的实现方法

    这篇文章主要介绍了koa2服务配置SSL的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • Centos7 安装Node.js10以上版本的方法步骤

    Centos7 安装Node.js10以上版本的方法步骤

    这篇文章主要介绍了Centos7 安装Node.js10以上版本的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • 原生nodejs使用websocket代码分享

    原生nodejs使用websocket代码分享

    本文给大家分享的是在原生的nodejs中如何使用websocket实现信息传输,非常实用,有需要的小伙伴可以参考下
    2018-04-04
  • nodejs结合socket.io实现websocket通信功能的方法

    nodejs结合socket.io实现websocket通信功能的方法

    这篇文章主要介绍了nodejs结合socket.io实现websocket通信功能的方法,结合实例形式分析了nodejs结合socket.io实现websocket通信的具体步骤与相关操作技巧,需要的朋友可以参考下
    2018-01-01
  • nodejs进阶(6)—连接MySQL数据库示例

    nodejs进阶(6)—连接MySQL数据库示例

    本篇文章主要介绍了nodejs进阶(6)—连接MySQL数据库示例,详细的介绍了NodeJS操作MySQL数据库,作为应用最为广泛的开源数据库则成为我们的首选,有兴趣的可以了解一下。
    2017-01-01
  • Node.js实现修改文件字符集功能的具体过程

    Node.js实现修改文件字符集功能的具体过程

    在日常生活、工作中,我们经常会遇到需要处理不同编码格式的文件,有时,在尝试打开这些文件时会遇到乱码,原因通常是文件的编码与我们使用的文本编辑器或编程语言的默认编码不匹配,这篇文章将介绍Node.js修改文件字符集的实现思路和具体实现过程
    2024-08-08
  • Node.js Mongodb 密码特殊字符 @的解决方法

    Node.js Mongodb 密码特殊字符 @的解决方法

    在去年的 DB 勒索事件之后, 不少的同学开始加强 Mongodb 的安全性, 其中一种办法就是设置复杂的密码. 那么如果设置的密码里包含一些如 “@”, “:” 一样的特殊字符,怎么处理呢?下面小编给大家带来了Node.js Mongodb 密码特殊字符 @的解决方法,一起学习吧
    2017-04-04
  • windows8.1+iis8.5下安装node.js开发环境

    windows8.1+iis8.5下安装node.js开发环境

    这篇文章主要介绍了windows8.1+iis8.5下安装node.js开发环境的方法,需要的朋友可以参考下
    2014-12-12

最新评论