javascript 动态调用-JS调用C++动态库dll

2023-09-01 0 4,898 百度已收录

经常问的问题

问题 1. *.nodeisnotavalidWin32application

问题 2. 错误:DynamicLinkingError:Win32error193

问题 3. 错误:DynamicLinkingError:Win32error126

问题 4. 错误:DynamicSymbolRetrievalError:Win32error127

实现步骤和最少代码

1.安装工具库

2.导出依赖

3.导入动态库方法

4.调用导入方法

结尾

环境总结Nodejs传输dll、环境安装错误处理

1.安装Visual Studio 2019

2.nodev16.14.0或以上

3、安装python-2.7.15并配置他的环境变量

4.全局安装node-gypv9.0.0

5.全局安装最新的windows-build-tools

6.最后在项目中安装最新的ffi-napi

以上6步完成后就可以使用node来调用dll文件了

前言

在Electron的开发过程中,很多时候会遇到调用C++动态库dll的需要。 使用JS调用dll库听起来很高端。 JS和C++是两种基本没有重叠的语言。 这时,火花四溅。 明天我会在Electron的基础上介绍这个神奇的使用过程以及可能遇到的各种问题。 如果后端朋友有兴趣,欢迎收藏实践!

文本

不得不说,想要实现JS调用C++ dll动态库,需要依赖第三方工具和中间件。

Nodejs有很多相关的工具类,它们可以方便地使用JavaScript加载和调用dll动态库,同时还负责处理跨JavaScript和C类型转换问题。

类似的插件大致如下:

1. 节点ffi-napi

仓库地址:

2. 节点ffi

仓库地址:

常问问题

先说一下可能遇到的问题,文末给出一个极简的代码示例。

问题 1. *.nodeisnotavalidWin32application

错误信息:

错误:\?G:projectworkelectron-quick-startnode_modulesffi-napibuildReleaseffi_bindings.nodeisnotavalidWin32application。

\?G:projectworkelectron-quick-startnode_modulesffi-napibuildReleaseffi_bindings.node

atprocess.func[asdlopen](电子/js2c/asar.js:140:31)

atObject.Module._extensions..node(内部/模块/cjs/loader.js:1034:18)

问题截图:

原因:依赖库不是32位的。

解决方案:这个问题通常比较常见,因为很多依赖库可能与目标应用类型不一致,大多数情况发生在node_modules的依赖库中。

解决起来也很简单,只需重新构建即可。

在依赖库中执行以下命令:

节点-gypcleanconfigurebuild--verbose--arch=ia32

如果你还不知道怎么做,可以参考我之前写的一篇文章——《Electron FAQ 9-*.nodeisnotavalidWin32application》

问题2:错误:DynamicLinkingError:Win32error193

错误信息:

G:项目工作电子快速启动dll.dll

(节点:23644)UnhandledPromiseRejectionWarning:错误:DynamicLinkingError:Win32error193

atnewDynamicLibrary(G:projectworkelectron-quick-startnode_modulesffi-napilibdynamic_library.js:75:11)

atObject.Library(G:projectworkelectron-quick-startnode_modulesffi-napiliblibrary.js:47:10)

在 G:projectworkelectron-quick-startmain.js:81:18

(节点:23644)UnhandledPromiseRejectionWarning:错误:DynamicLinkingError:Win32error193

atnewDynamicLibrary(G:projectworkelectron-quick-startnode_modulesffi-napilibdynamic_library.js:75:11)

atObject.Library(G:projectworkelectron-quick-startnode_modulesffi-napiliblibrary.js:47:10)

在 G:projectworkelectron-quick-startmain.js:81:18

问题截图:

原因1.调用的动态库dll是32位的,但目标模块需要64位的。

解决:

重新编译64位dll动态库javascript 动态调用,问题解决。

如果我们换成64位的dll动态库,仍然存在这个问题。 大概率的问题是dll缺少对应的依赖dll库。

原因2.缺少依赖库。

解决:

从事windows系统开发的人都知道,我们平时开发的工具dll库或多或少都会依赖系统或者第三方的dll库。 这也是dll动态库的优点,可以动态依赖,动态调用。 如果我们想省事的话,可以直接将需要的系统或者第三方库以静态库的形式打包,这样收到后就可以使用,大概率就不会出现这个问题了。 因此,我们可以使用depends等工具来检查dll的依赖库是否完整。

问题 3. 错误:DynamicLinkingError:Win32error126

错误信息:

(节点:17224)UnhandledPromiseRejectionWarning:错误:DynamicLinkingError:Win32error126

atnewDynamicLibrary(G:projectworkelectron-quick-startnode_modulesffi-napilibdynamic_library.js:75:11)

atObject.Library(G:projectworkelectron-quick-startnode_modulesffi-napiliblibrary.js:47:10)

在 G:projectworkelectron-quick-startmain.js:81:18

问题截图:

原因:路径问题,很可能是没有找到需要的dll动态库。

解决方案:防止这个问题的原因是尽可能使用绝对路径,防止使用相对路径。 其实如果能保证路径没有问题,这个就随便了。

因为Electron的调试启动路径与安装后的启动路径不同,所以需要注意。

注意:Electron在开发模式下启动的路径是node_modules/electron/目录。

问题 4. 错误:DynamicSymbolRetrievalError:Win32error127

错误信息:

(节点:21764)UnhandledPromiseRejectionWarning:错误:DynamicSymbolRetrievalError:Win32error127

atDynamicLibrary.get(G:projectworkelectron-quick-startnode_modulesffi-napilibdynamic_library.js:113:11)

在 G:projectworkelectron-quick-startnode_modulesffi-napiliblibrary.js:55:21

atArray。 forEach()

问题截图:

造成这个问题的原因通常是dll的问题。 也就是说生成的C++ dll动态库有问题,通常是因为没有导入方法的符号javascript 动态调用,所以调用dll时找不到对应的方法。

最简单的原因就是导入function方法时没有添加extern“C”。

没想到,我也遇见了他。 。 。 ?

那么为什么 extern "C" 会影响导入符号呢? 那么我们需要简单介绍一下它的功能。

本质功能是正确实现C++代码调用其他C语言代码。

当我们添加extern "C"时,它会指示编译器按照C语言(而不是C++)的方法来编译这部分代码。

因为C++支持函数重载,为此,编译器在编译函数时,也会将函数的参数类型添加到编译后的代码中,而不仅仅是函数名; 而C语言不支持函数重载,所以在编译C语言代码的函数时,不会带上函数的参数类型,通常只包含函数名。 这个功能是非常有利的,因为在C++出现之前,很多代码都是用C语言写的,但是底层库也是用C语言写的。 为了更好地支持原来的C代码和已经写好的C语言库,需要在C++中尽可能的支持C,所以extern“C”就成为了必然的选择。

说了这么多,赶快在你的动态库的方法中添加extern "C",然后重新编译一份。

看看问题是否解决。

最后附上代码示例:

#include 
#if defined(WIN32) || defined(_WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
extern "C" EXPORT int sum(int a, int b) {
 return a + b;
}

问题5:安装失败,提示node-gyprebuild failed

如果windows-build-tools没有正确安装,npm installfi时会出现错误。

如果已经安装了node-gyp,则需要先删除C:UsersAdministrator.node-gyp目录,然后再卸载npmuninstallnode-gyp。

重新安装 npminstall-gnode-gyp。

之后安装

npm install --global windows-build-tools

安装完成后,执行npminstallfi。

实现步骤和极简代码

遇到以上问题并不容易。

接下来我就介绍一下具体的步骤。

1.安装工具库

安装文章开头介绍的任意工具库,这里以ffi-napi为例,具体命令:

尼普米菲纳皮

2.导出依赖库

减少代码中ffi-napi依赖库的引用。

代码:

var ffi = require('ffi-napi') 

3.导入动态库方法

那么,就是需要用到使用ffi-napi导入dll动态库的方法了。 需要注意的是,导入的声明语句必须与dll动态库中C++方法的名称、参数表、返回值一致。

这里以求和方法intsum(inta, intb)为例,代码如下:

var dllPath = path.resolve("cpp.dll");
var dllfuns = ffi.Library(dllPath, {
    'sum': [ 'int', [ 'int', 'int' ] ],
});

4.调用导入方法

这一步也很简单,代码如下:

  console.log('=======================================')
  var s = dllfuns.sum(1,2); // 调用方法
  console.log("call c++ dll function sum, result: ", s);
  console.log('=======================================')

代码执行结果:

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript 动态调用-JS调用C++动态库dll https://www.wkzy.net/game/186794.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务