NodeJS地址: Electron版本:
Edge.js源码: electron-edge-js:
Node-ffi源码: node-win32-api: winmm.dll:
开源项目 edge 可以帮助我们实现 Node 和 .NET 之间的相互调用 我们最常见就是使用它来调用C#的代码方法或者C#生成的DLL文件的方法 C/C++生成的DLL就要用Node-ffi 因为我是要调用系统的DLL所以主要使用Node-ffi
node-ffi是一个用于使用纯JavaScript加载和调用动态库的Node.js插件。它可以用来在不编写任何C ++代码的情况下创建与本地DLL库的绑定。同时它负责处理跨JavaScript和C的类型转换。
与相比,此方法有如下优点:
缺点是:
为什么需要使用DLL
安装
通过类,在C代码和JS代码之间实现了内存共享,类型转换则是通过、、实现。由于/包含C原生代码,所以安装需要配置Node原生插件编译环境。
根据需要安装对应的库
如果是项目,则项目可以安装electron-rebuild插件,能够方便遍历中所有需要的库进行重编译。
在package.json中配置快捷方式
之后执行npm run rebuild 操作即可完成的重编译。
简单范例
DLL源码
调用DLL
变量类型
C语言中有4种基础数据类型—-整型 浮点型 指针 聚合类型
基础
整型、字符型都有分有符号和无符号两种。
在不声明unsigned时 默认为signed型
中会缩写成, 如 对应 。
浮点型中有 。
库中已经帮我们准备好了基础类型的对应关系。
DWORD为类型,下文会详细说明
更多拓展可以去
中,既可以通过ref.types.xxx的方式申明类型,也可以通过文本(如)进行申明。
字符型
字符型由构成,在编码中一个汉字占2个字节,在UTF-8中占用3~4个字节。一个默认一字节。根据所需字符长度创建足够长的内存空间。这时候需要使用库。
在传递中文字符型时,必须预先得知库的编码方式。node默认使用UTF-8编码。若DLL不为UTF-8编码则需要转码,推荐使用iconv-lite
转码
注意!使用encode转码后为类,可直接作为当作类型
iconv.encode(str.’gbk’)中gbk默认使用的是储存。假如C代码需要的是,则需要将buffer中的数据使用int8类型转换。
C代码为字符数组/设置的返回值,通常返回的文本并不是定长,不会完全使用预分配的空间,末尾则会是无用的值。如果是预初始化的值,一般末尾是一大串的,需要手动做,如果不是预初始化的值,则末尾不定值,需要C代码明确返回字符串数组的长度。
内置简写
ffi中内置了一些简写
只建议使用’string’。
字符串虽然在js中被认为是基本类型,但在C语言中是以对象的形式来表示的,所以被认为是引用类型。所以string其实是char 而不是char
聚合类型
多维数组
遇到定义为多维数组的基本类型 则需要使用ref-array进行创建
C
JS
结构体
结构体是C中常用的类型,需要用到进行创建
C
JS
指针
指针是一个变量,其值为实际变量的地址,即内存位置的直接地址,有些类似于JS中的引用对象。
C语言中使用来代表指针
例如 int a 则就是 整数型a变量的指针 , 用于表示取地址
实现指针的原理是借助,使用类在C代码和JS代码之间实现了内存共享,让成为了C语言当中的指针。
注意,一旦引用,会修改的,替换和注入一些方法,请参考文档
要明确一下两个概念 一个是结构类型,一个是指针类型,通过代码来说明。
可以通过直接得到一个引用对象

回调函数
C的回调函数一般是用作入参传入。
注意!如果你的CallBack是在setTimeout中调用,可能存在被GC的BUG
代码实例
举个完整引用例子
C
JS
常见错误
这个错误有三种原因
Path设置
如果你的DLL是多个而且存在相互调用问题,会出现错误3。这是由于默认的进程是二进制文件所在目录,即目录而不是DLL所在目录,导致找不到DLL同目录下的其他引用。可以通过如下方法解决:
闪崩问题
实际调试的时候,很容易出现内存错误闪崩,甚至会出现断点导致崩溃的情况。这个是往往是因为非法内存访问造成,可以通过日志看到错误信息,但是相信我,那并没有什么用。C的内存差错是不是一件简单的事情。
GetLastError
简单说通过winapi来调用DLL,这导致永远返回0。最简单方法就是自己写个来绕开这个问题。
参考Issue 参考PR
PVOID返回空,即内存地址闪崩
winapi中,经常通过判断返回的指针是否存在来判断是否成功,但是在中,对的内存地址会造成程序闪崩。必须迂回采用指针的指针类型进行特判
JS
附录
DLL分析工具
自动转换工具
tjfontaine大神提供了一个,可以根据头文件,自动生成函数申明,注意这个需要环境,简单用KOA包了一层改成了在线模式,可以丢到VPS中运行。
WINAPI
winapi存在大量的自定义的变量类型,waitingsong大侠的轮子 中完整翻译了全套中的类型,而且这个项目采用TS来规定FFI的返回Interface,很值得借鉴。
注意!里面的类型不一定都是对的,相信作者也没有完整的测试过所有变量,实际使用中也遇到过里面类型错误的坑。
转载自:
实例-禁用窗口右键菜单
现在使用 ffi 调用 user32.dll 中的 GetSystemMenu 函数来解决这个问题,首先新建一个 user32.js 文件,为了展示 ffi ,我多定义了几个API函数:
修改 app.js 文件,首先导入 user32.js:
然后修改如下内容:
再运行项目,系统菜单就消失的无影无踪了。
C#代码
先看看C#代码怎么写
调用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/163195.html