electron调用第三方dll

前言

上一篇文章有说到过我们可能会遇到使用Electron调用第三方提供的dll,今天就来详细的说一下如何调用dll库,坑巨多,让我娓娓道来😣,如果对Electron还不太熟悉的小伙伴可以看我的上一篇文章,下面的内容可能会多次提到。建议看完上一篇,再来看这一篇会更加清晰哦🤣。

依赖库选择

当收到这个需求的时候,肯定也是一脸蒙😌,我一个前端也没写过dll,我怎么来调用啊?做过nodejs的同学应该能清楚它提供了这样的能力🤙,如果是用c++生成的dll可能会用到ffi-napi这个库,如果是c#生成的dll就会使用到edge这个库😄,因为我们公司都是用c#编写的dll,所以我会主要介绍一下edge,c++调用dll的文章可以看这篇我有好多坑都是看了这篇文章才清楚,抱拳了✊。

NodeJs调用dll

  • 创建demo项目
    1
    2
    #找到一个空目录执行
    npm init --yes
  • 安装edge
    1
    npm install edge --save
  • 创建index.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 官网示例
    var edge = require('edge');
    var helloWorld = edge.func(`
    async (input) => {
    return ".NET Welcomes " + input.ToString();
    }
    `);
    helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
    });
  • 运行(噩梦降临👇)
    1
    node index.js
    不出意外它报错了,报错内容如下。


根据报错内容我们可以发现,edge尚未针对 node.js 版本v16.14.0进行预编译🍺,我第一点想的就是是不是我的nodejs版本太高了🎥,但是它有没说让我降到哪个版本我应该怎么改啊😣,于是我就去Google🦠,发现edge只支持低版本的nodejs并且作者已经好久不维护了,如果使用的是12.x以上版本的nodejs需要使用edge-js这个库(我滴个亲娘嘞🤦‍♀️)。

好的地方就是它的用法与edge只需要将引用的edge改成edge-js就可以了

  • 修改之后,大功告成

  • 找你的c#同时去开发一个dll,告诉她只输出一句话就行,分分钟搞定😄,如果不好意思找的同事,我也分享一下我的Demo.dll,具体内容可以查看下方👇。

    链接:https://pan.baidu.com/s/1K6teI3la2sBDkKNpAPjAPA
    提取码:z3s0

  • 在项目的根目录引入dll文件

  • 修改index.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const edge = require('edge-js');
    const path = require('path');
    var invoke1=edge.func({
    assemblyFile:path.resolve("Demo.dll"), //找到对应的dll文件
    typeName:"Demo.Startup", // C#中class的名字就是StartUp
    methodName: "Invoke" // 导出dll的方法名
    })
    invoke1("入参",function(err,result)
    {
    if (err) throw err;
    console.log(result);
    });
  • 运行(噩梦再次降临👇)
    1
    node index.js
    你可能会遇到如下错误

解决方案(联系的dll开发同事,将下面的话转述给他)

引入C#类库时不要使用netcore版本🥩,需要使用.net framework 4.x版本的类库(解决办法简单,找办法的经历实在太过痛苦🎍)

  • 重新引入dll,大功告成

Electron中调用dll

edge-js官网中要是看的仔细的小伙伴可以发现如果在Electron中调用dll需要使用electron-edge-js库而不是edge-js上一篇文章已经说过了怎么创建Electron项目这里就不再赘述了,只把新增的代码在这里说一下。

  • 在上一章的render->index.js中增加如下代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 调用dll
    const edge = require('electron-edge-js');
    console.log(path.resolve("Demo.dll"))
    var invoke1 = edge.func({
    assemblyFile: path.resolve("Demo.dll"),
    typeName: "Demo.Startup",
    methodName: "Invoke"
    })
    invoke1("入参", function (err, result) {
    if (err) throw err;
    console.log(result);
    });
  • 运行(噩梦第三次降临👇)
    1
    npm start 
    同样的问题,这次说的是electron的版本太高了(我本地的nodejs版本是16.14.0)还是没有告诉我Electron应该降到什么版本🥙。

    在官网我看到了这样一张图。

我抱着试试看的态度把electron的版本降低到了13.0.0(它成功了,但其实我没有降低nodejs的版本)
electron:13.0.0 NodeJs:16.14.0

  • 重新运行
    1
    npm start 

在集成Electron的vue项目中调用dll

可能有的小伙伴会问了,上面的案例已经在Electron中调用dll了为什么还要在单独列出来一个类目啊?

答:我也不想啊,你试试就知道了,他是真的不一样呀😥

  • 在上一章创建的vue项目的根目录增加resources目录将dll文件拷贝过去。

  • 给项目中的某个元素增加一个点击事件,内容如下,其实跟上面的代码都是一样的
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const edge = require('electron-edge-js');
    const path = require('path')
    var invoke1 = edge.func({
    assemblyFile: path.resolve("resources/Demo.dll"),
    typeName: "Demo.Startup",
    methodName: "Invoke"
    })
    invoke1("shuchuneirong", function (err, result) {
    if (err) throw err;
    console.log(result);
    });
  • 运行(噩梦他说来就来啊👇)
    1
    npm run electron:serve
    还是同样的错误!!!!我是真的蒙了,我刚刚不是解决了吗?我是解决个寂寞吗?,我已经出现自我怀疑了

我又想起了官网的那种图是不是因为我的nodejs版本太高了🚞。因为官网写的是electron13.x对应的nodejs14.16.0🚔,于是我又开始降低nodejs的版本这块也有很多坑🛸,后面会专门写一篇使用nvm管理多版本nodeJs,果然上天这次没有眷顾我 我失败了,我下了三个版本的node都是同样的问题🤶。

经过一天的浏览我看到文章开头的那篇文章找到了办法,实际办法就在官网。

  • 需要在vue.config.js中增加红框的代码

因为electron-edge-js模块中包含原生C代码,所以要在运行的时候再获取,而不是被webpack打包到bundle中(解决办法简单,找办法的过程好苦哦)

  • 重新运行,大功告成

Electron带dll打包

运行时正常,打包之后异常,报如下错误


看描述应该是找不到我们的Demo.dll文件了,因为打包的时候👩‍🏫,没有将项目中的dll文件拷贝到最终生成的dist_electron\win-unpacked 文件夹中🛀。

  • 解决方案

总结

Electron调用dll的坑确实很多,相同的问题采用的是不同的解决办法,还是需要一点一点去摸索,反复切换nodeJs版本的时候也尝尽了苦头,下次再说吧。非常感谢参考链接下的作者👇,争做分享先锋,不做白嫖党。加油!🙋‍♂️

参考链接

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!谢谢