IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> node-ffi调用C++编译的动态链接库踩坑记录 -> 正文阅读

[C++知识库]node-ffi调用C++编译的动态链接库踩坑记录


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、安装相关依赖

旧版node-ffi不支持高版本的node环境,其他博主也有详细介绍,我就不再赘述了,现在使用V12以上的node版本需要用到ffi-napi以及相关的库,由于该库需要使用到node-gyp进行编译所以需要提前安装好相关环境,node-gyp的安装可以参考这几篇文章nodeffi入门到放弃electron使用nodeffi

安装好node-gyp的环境以后现在安装ffi-napi相关的库,官方仓库github

npm install ffi-napi
npm install ref-napi
npm install ref-napi
npm install ref-array-napi

二、使用步骤

1.准备好动态链接库

使用Viasual Studio 2017新建一个dll的项目
在这里插入图片描述
在这里插入图片描述
创建好项目以后就会得到一个默认的这样的文件
在这里插入图片描述

然后分别在头文件pch.h和源文件pch.cpp里面添加测试代码

// pch.cpp
int funAdd(int a, int b)
{
	return (a + b);
}

在这里插入图片描述

// pch.h
extern "C"
{
	__declspec(dllexport) int funAdd(int a, int b);
}

在这里插入图片描述

别忘记按住Ctrl + s保存代码

然后编译成dll文件

注意:编译的时候默认编译成64位的就行了
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.引入库

在项目中新建一个index.js文件和一个dll文件夹(存放刚刚编译的dll文件)
在这里插入图片描述

index.js代码如下(示例):

const ffi = require('ffi-napi');
const ref = require('ref-napi');
const ArrayType = require('ref-array-napi');
const path = require('path');

function testDll(){
  const dll = './dll/DLL4.dll';
  const filePath = path.resolve(dll);
  const lib = new ffi.Library(filePath, {
    'funAdd': // 声明这个dll中的一个函数
    [
      'int', ['int', 'int'], // 用json的格式罗列其返回类型和参数类型
    ],
  });
  const result = lib.funAdd(1, 2);
  console.log(result);
}

然后在控制台执行

node index.js

在这里插入图片描述
如果没有报错那就恭喜你以及可以成功调用dll文件了

如果遇到了类似这样的报错,Dynamic Linking Error: Win32 error 193,那就是你的动态链接库可能是32位的而你的操作系统是64位的。如果想测试复现这个错误,可以在上面的介绍中将编译的配置项改为x86然后重新编译就可以得到一个32位的dll文件。

请查看相关博客描述常见的错误信息,在这里我也不做赘述了,Electron——常见动态链错误
node-ffi调用dll踩坑记录

dll查看器的使用

在调试过程中如果遇到了Dynamic Linking Error: Win32 error 127的报错,我遇到了三种情况

  1. 你在new ffi.Library的参数里面写的函数名与C++代码的函数名不一致,比如C++里面是funAdd函数你写成funadd
  2. 也可能是函数的参数类型错误,比如funAdd函数的参数类型是int你写成double
  3. 还有一种就是动态链接库里面还引用了别的动态链接库,但是你本地的电脑环境里面没有这个文件引用的别的dll文件

第三种情况就可以使用dll查看器检查你的dll文件是否有问题,参考Win10 查看 DLL 中的函数

我会将这个dll查看器上传到我的资源我的资源中,方便大家下载,免费的哦

把工具下载好了以后,解压文件,找到DependenciesGui.exe这个文件双击运行
在这里插入图片描述
在这里插入图片描述
可以正常执行的dll文件应该是一下图片中的内容
左侧是你的dll文件依赖的一些其他dll文件的文件树,右侧就是dll文件里面函数名,地址等信息
在这里插入图片描述

那我们现在打开一个有问题的dll文件,(这个dll文件是通过Cmake的方式编译的,这个dll文件还依赖了mingw的dll文件)
在这里插入图片描述
找到报错的dll文件
在这里插入图片描述
然后我找了报错的dll文件

在这里插入图片描述
在这里插入图片描述
所以报错的原因已经找到了,就是nodejs在调用A这个dll文件的时候,A还依赖了其他的dll文件,但是你的系统里面找不到A依赖的文件所以导致报错,至于报错信息为什么是Dynamic Linking Error: Win32 error 127还有待研究,估计得看源码。

由于该动态链接库是Cmake编译的,而且在编译的时候选择了动态库的形式,所以把这个编译出来的dll库放到其他环境可能就无法运行。最好的解决办法就是编译成静态库,简单的说就是把你编译的目标dll文件所依赖的dll文件一起打包,就像克隆别人的代码仓库,把别人的代码仓库里面的node_modules包一起克隆。如何编译静态库 请参考Clion创建和调用静态库

__declspec(dllexport)关键字

还有一个关键的地方就是在.h的头文件中函数声明前面添加 __declspec(dllexport)关键字,其实不添加这个关键字编译出来的dll文件也可以正常运行,只不过在dll查看器里面看不到你声明的函数,因为头文件不参与编译。

下面放两张参考图
在这里插入图片描述
在这里插入图片描述


总结

总之踩了各种各样的坑终于把Cmake编译的dll文件跑起来了,踩坑的原因也是因为自己对C++不熟悉,对Cmake不熟悉,对编译原理不熟悉,填坑的时候耗费了大量的时间去查资料。希望对大家有帮助。最好来个一键三联鼓励一下,以后我会多多分享开发中常见的填坑技巧。谢谢大家🎉?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-15 11:29:21  更:2022-05-15 11:29:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:33:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码