您的位置 首页 golang

「electron学习笔记」关于electron如何调用dll以及遇到的一些坑

使用ffi-napi+ref-napi 调用dll

ffi-napi 是一个用于 js 加载和调用动态库的 node.js 插件。
ref-napi 提供了 c++ 的一些类型,可以将 buffer 实例转化成“指针”。

前期准备

下载 windows-build-tools, 需要用管理员模式运行,
npm install –global –production windows-build-tools -vs2015
这个会自动下载 python2.7 和 c++ 的编译插件。

安装

安装时可能遇到的坑

提示 node-gyp rebuild 的报错,这种情况一般是 node-gyp 的版本问题,安装最新版本覆盖一下就可以,执行 npm install node-gyp ,然后在 package.json 删掉这个依赖。

使用

1、创建dll

使用vs2019 创建

2、实现文件复制功能

头部引用:

 # include <windows.h>
#include<shellapi.h>
#include<atlstr.h>
#include<shlobj.h>  
  void  unicodeToUtf8(wchar_t* unicode,CString& re){
    int len;
    len = WideCharToMultiByte(CP_UTF8,0,unicode,-1,NULL,0,NULL,NULL);
    char* szUtf8 = (char*)malloc(len + 1);
     memset (szUtf8, 0, len + 1);
    WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL, NULL); 
    CString    temp(szUtf8);
    re = temp;
    free(szUtf8);
    szUtf8 = NULL;
}
void GetFileFromClipboard(char* path){
    UINT uDropEffect = RegisterClipboardFormat(_T("Preferred DropEffect"));
    UINT cFiles = 0;
    if ( OpenClipboard (NULL))
    {
        HDROP hDrop = HDROP(GetClipboardData(CF_HDROP/*CF_UNICODETEXT*/));
        if (hDrop)
        {
            cFiles = DragQueryFile(hDrop, (UINT)-1, NULL, 0);
            TCHAR sz File [MAX_PATH];
            CString str = "";
            for (UINT count = 0; count < cFiles; count++)
            {

                DragQueryFile(hDrop, count, szFile, sizeof(szFile));
                CString tmp(szFile);
                if (count + 1 != cFiles) {
                    str = str + tmp + L"|";
                }
                else {
                    str = str + tmp;
                }
            }
            CString re="";
            unicodeToUtf8(str.AllocSysString(), re);
             strcpy _s(path,  strlen (re) + 1,re);
        }
    }
     Close Clipboard();
}  

3、生成dll的注意事项

要注意打包的位数,不然在调用时会报错。

js 使用 ffi 引用:

 const dllPath = "copy.dll";
let buffer:any=  ref.allocCString('');
const library = ffi.Library(dllPath, {
    GetFileFromClipboard: ["void", [ref.types.CString]],
});
library.GetFileFromClipboard(buffer);
const re = ref.readCString(buffer, 0);
buffer = null;
console.log(re)  

使用 字符串 传参的一些坑

在之前,我返回复制的内容都是通过 return 返回的。在后来测试时,发现有一定几率返回的是乱码。

一开始以为是编码问题,找了各种转码、代码都不行,后面想到在c++ 中字符串是存指针的,返回可能已经被释放掉了,所以要使用从外面申请内存存进去。

其他坑

之前试过使用其他语言写 dll,比如 golang,对于非指针操作还算正常,但是有指针操作情况下会报错,估计是非标准的问题。

总结

总的来说,electron 调用 dll 还是比较简单的,难点在于编写 dll 上,毕竟作为前端人员大多数情况下使用的是 js ,c++ 基本很少用到。而 electron 作为前端写桌面的玩具,能用 js 实现就尽量使用 js ,不建议再用其他方式。

给大家分享更多 electron 实战中的点滴,如果大家对此感兴趣,欢迎各位关注、留言,大家的支持就是我的动力!

文章来源:智云一二三科技

文章标题:「electron学习笔记」关于electron如何调用dll以及遇到的一些坑

文章地址:https://www.zhihuclub.com/100179.shtml

关于作者: 智云科技

热门文章

网站地图