【electron-vue】在electron中调用C++的dll(ffi库)
正如Node.js介绍4-Addon里说的,让JavaScript调用c++代码有三种方法:1.在子进程中调用C++程序2.调用C++的dll参考关于在electron中调用C++动态库的经验总结3.使用addon(实际上addon也是一个动态链接库)参考Node.js v14.8.0 文档 C++ 插件参考Electron & C++ 快速开发桌面Web "混合"应用这里选用第二种来实验
正如 Node.js介绍4-Addon 里说的,让JavaScript调用c++代码有三种方法:
1.在子进程中调用C++程序
2.调用C++的dll
3.使用addon(实际上addon也是一个动态链接库)
参考 Electron & C++ 快速开发桌面Web "混合"应用
参考 【electron-vue】在electron中调用Nodejs生成的c++插件
这里选用第二种来实验
安装
1、安装 node-gyp 参考 安装node-gyp
由于node程序中需要调用一些其他语言编写的 工具 甚至是dll,需要先编译一下,否则就会有跨平台的问题
npm install node-gyp -g
2、安装 ffi
是一个Node.js插件,用于使用纯JavaScript加载和调用动态库。它可以用来创建到本机库的绑定,而无需编写任何C ++代码
另:node -ffi弃用了,改为了ffi。
npm install ffi --save
我本地是有安装vs和python环境的
安装后报错
error C2660: “v8::Value::BooleanValue”: 函数不接受 0 个参数
error C2660: “v8::Value::Uint32Value”: 函数不接受 0 个参数
error C2661: “v8::Object::Set”: 没有重载函数接受 2 个参数
当我node版本是v14.8.0的时候,会报错,看了github上很多类似的问题,很多人都反映说将node降级就可以。
卸载node,安装v11.10.0。(我好像成功了!!!!)
nodejs调用系统dll
testdll.js
const ffi = require("ffi");
const User32 = ffi.Library('user32', {
'GetWindowLongPtrW': ['int', ['int', 'int']],
'SetWindowLongPtrW': ['int', ['int', 'int', 'long']],
'GetSystemMenu': ['int', ['int', 'bool']],
'DestroyWindow': ['bool', ['int']]
})
console.log(User32.GetWindowLongPtrW);
终端输入,回车
node testdll.js
electron 调用自己生成的dll
1、报错 was compiled against a different Node.js version using
安装electron-rebuild
npm install --save-dev electron-rebuild
执行rebuild
"./node_modules/.bin/electron-rebuild.cmd"
下图是多次执行后的结果
执行rebuild报错
设置python路径(D:\python\2.7.13.1_64bit\python-2.7.13.amd64\python.exe改成自己python路径)
npm config set python D:\python\2.7.13.1_64bit\python-2.7.13.amd64\python.exe
rebuild成功
2、报错 Error: Dynamic Linking Error: Win32 error 126
参考 problem :Error: Dynamic Linking Error: Win32 error 126 ?
输出了路径,发现路径错了
3、报错 Error: Dynamic Symbol Retrieval Error: Win32 error 127
参考 Got Error “Dynamic Symbol Retrieval Error: Win32 error 127” when load DlL from nodejs
生成的c++ dll有问题,没有导出,所以调用dll的时候找不到对应的方法
4、报错 Error: Dynamic Linking Error: Win32 error 193
参考 记录 electron-vue 通过node ffi调用dll文件踩的坑
dll错生成了86位的。改成64位即可
c++ dll测试代码
testDll.h
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 TESTDLL_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// TESTDLL_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
//#ifdef TESTDLL_EXPORTS
//#define TESTDLL_API __declspec(dllexport)
//#else
//#define TESTDLL_API __declspec(dllimport)
//#endif
#define TESTDLL_API __declspec(dllexport)
// 此类是从 dll 导出的
class TESTDLL_API CtestDll {
public:
CtestDll(void);
// TODO: 在此处添加方法。
};
extern "C"
{
TESTDLL_API int ntestDll;
TESTDLL_API int fntestDll(void);
TESTDLL_API double Add(double a, double b);
TESTDLL_API int foo(int value);
}
testDll.cpp
// testDll.cpp : 定义 DLL 的导出函数。
//
#include "testDll.h"
// 这是导出函数的一个示例。
TESTDLL_API int fntestDll(void)
{
return 0;
}
TESTDLL_API double Add(double a, double b) {
return a + b;
}
// 这是已导出类的构造函数。
CtestDll::CtestDll()
{
return;
}
TESTDLL_API int foo(int value)
{
return value;
}
electron里js的测试代码
var ffi = require('ffi');
var path = require('path');
var dllPath = path.resolve('testdll\\TESTDLL');
console.log("--------------------------------------: " + dllPath);
const lib = ffi.Library(dllPath, {
'foo': [
'int', ['int'],
],
'Add': ['double', ['double', 'double'], ],
});
var result = lib.Add('1.0', '2.0');
console.log(result);
var result = lib.foo('1111');
console.log(result);
成功
参考 electron教程(三): 使用ffi-napi引入C++的dll
生成的c++ dll因为没用extern "C"的方式导出,一直报错,找不到方法。
更多推荐
所有评论(0)