windows下electron + ffi-napi + dll不完全踩坑指南

本文记录我在electron中使用ffi-napi加载dll时所踩的坑,以及如何排查和解决问题(windows平台)。

Win32 error 127

127是我最开始遇到的问题,网上查找到的说法是生成的c++ dll有问题,没有导出。这个需要反馈给c++开发查看,让他们导出后重新编译。如果开发的电脑上已经装了 visual studio,可以查看这篇文章,查看dll是否导出了函数。

Win32 error 126

解决了127的问题,本地开发调试的时候也很顺利,偏偏打包安装到测试机上就遇到了126这个错误。触发这个错误一般都是路径问题:

  1. dll本身路径不存在
  2. dll所依赖的其他dll不存在

我就是遇到的第二种情况,既然依赖不存在,那么就先查下依赖了哪些dll:

  1. 如果安装了visual studio,可以用 visual studio 里的 x86 Native Tools Command Prompt for VS 2022 (32位的用这个, 64位的用x64),查看依赖哪些dll

    1
    dumpbin /dependents [dll所在路径]
  2. 没安装vs的话,强烈推荐Dependencies这个软件。有可视化程序,查看dll的依赖,标记当前电脑中缺失的dll。

最后排查的原因也是令人哭笑不得。。。测试机上缺少的dll是vcruntime140d.dll,这是debug模式下编译的dll所依赖的库,我本机上装了vs,系统中就有vcruntime140d.dll这个dll,开发的时候没任何问题。

而测试机上只有vcruntime140.dll这个dll,只要在release模式下重新编译之后,生成的dll所依赖系统dll就变成vcruntime140.dll了。

所以在检查dll依赖的时候,注意下依赖的系统dll的文件名称是否以d结尾,如果是d结尾的,就是debug模式下生成的dll。

Win32 error 193

193大部分是electron是64位而dll是32位或者相反导致的。只要重新编译个同位数的dll或者打包相同位数的electron就能解决了。而我遇到的情况也比较尴尬,这得追溯到我所使用的electron-react-boilerplate,这个模板中有个 .gitattributes 文件,定义如下

1
2
3
4
5
6
7
8
9
10
11
12
*       text    eol=lf
*.exe binary
*.png binary
*.jpg binary
*.jpeg binary
*.ico binary
*.icns binary
*.eot binary
*.otf binary
*.ttf binary
*.woff binary
*.woff2 binary

这个文件定义了git对一些文件的处理方式,默认是按文本方式处理的,这里就埋下坑了。不同的系统会对二进制文件做啥处理,导致在jenkins服务器上打包应用的时候,dll这个文件损坏了,导致生成的应用安装在测试机上时报了193这个异常,解决方式就是加上:

1
2
*.node binary
*.dll binary

然后用完好的dll覆盖原来损坏的dll重新提交下,.node文件也是同样的,如果损坏了就会报一个is not win32 application的错。

如果你跟我一样也是用的electron-react-boilerplate,记得把用到的二进制文件添加到 .gitattributes 文件中,避免二进制文件损坏。

总结

在调用dll之前,先做如下检查:

  1. 检查dll文件是否有导出函数
  2. 检查dll文件依赖的其他dll是否有缺失,一般遇到缺失的都是系统dll,只要装个c++ runtime的程序就好了。
  3. 检查dll文件是否依赖 xxxxd.dll这类dll,如果有,告知dll提供方使用release重新编译。
  4. 确保dll与electron是相同位数,x64的electron只能调用x64的dll,x86的只能调用x86的。