注:本人初学记录,用法并非最优,仅供学习参考。
前提是我的项目结构如下:
//我的项目目录
ElectronApp
-build //发布输出目录
-node_modules //依赖包
-public
-src //前端api、views、vue代码
-api
-config
-util
-views
APP.vue
main.js
-electron //后端nodejs代码
-sdk //动态库存放
globalVars.js //全局变量
index.js //electron确定主进程
preload.js //预加载渲染进程
package.json
//package.json的build配置
"asarUnpack": [
"**/node_modules/**/*"
],
"extraResources": [ //sdk不压缩
{
"from": "./electron/sdk",
"to": "app.asar.unpacked/sdk"
},
],
一、Dynamic Linking Error: Win32 error 126
引用的路径错误,检查下DLL的路径是否正确,我的做法是,创建一全局的变量,并导出,在其他地方使用
// electron/globalVars.js
const { app } = require('electron')
const path = require('path')
module.exports = {
//SDK路径,存放dll或dylib的路径
sdkDir: app.isPackaged
? path.join(process.resourcesPath, 'app.asar.unpacked/sdk/')
: path.resolve('./electron/sdk/'),
//系统类型,这里可以直接用os获取
platform: 'win',
}
其他地方使用动态库
// electron/task/upload.js
const { sdkDir, platform } = require('../../globalVars')
let mydll
if (platform === 'mac') {
mydll = new ffi.Library(path.join(sdkDir, 'a.dylib'), {
function_1: [POINTER, ['int','string']],
function_2: ['void', [POINTER]],
})
} else {
mydll = new ffi.Library(path.join(sdkDir, 'a.dll'), {
function_1: [POINTER, ['int','string']],
function_2: ['void', [POINTER]],
})
}
关于动态库相互调用,导致的126问题
a、windows会优先在调用dll的当前目录查找,故可以将依赖的dll放在sdk下同级目录。
b、macos无法同级查找, 可以使用otool工具,修改dylib加载应用库的路径。
加入有动态库a.dylib,a.dylib调用了b.dylib,如下命令查看和修改
查看:otool -L a.dylib
显示: a.dylib(xxxxxxxxxxxxxx)
b.dylib(xxxxxxxxxxxxxx)
可以修改 install_name_tool -change b.dylib @loader_path/b.dylib a.dylib
查看:otool -L a.dylib
显示: a.dylib(xxxxxxxxxxxxxx)
@loader_path/b.dylib(xxxxxxxxxxxxxx)
二、Dynamic Linking Error: Win32 error 193
位数不对,根据系统来确定使用x86还是x64,可通过os进行判断引入相应的DLL
解决方法:a、同上,可以通过os获取系统的位数,加载如a_32.dll 或 a_64.dll
b、发布时候,--ia32 按照32位系统发布
几款工具使用:
win:Viewdll.exe,方便查看dll的依赖库
mac:otool,了解@loader_path,@rpath,@executable_path等