第01章 JAVA简介第02章 基础语法第02章 递归补充第03章 面向对象第04章 异常处理第05章 数组第06...
编译时与运行时 编译时: 即编译器对语言的编译阶段,编译时只是对语言进行最基本的检查报错,包括词法分析、语法分析等...
今天是我们这里特殊的日子。有一百对新人在江布拉克风景区旅行大型的婚礼,有很多地方的朋友们都慕名而来。看看这里的水,...
卧室、厨房间、客厅在装修过程中总有一些小细节我们会忽略, 这可能还我们的生活习惯以及专业知识有关系,不过这都不重要...
之间的相互调用 我们最常见就是使用它来调用C#的代码方法或者C#生成的DLL文件的方法 C/C++生成的DLL就要用Node-ffi 因为我是要调用系统的DLL所以主要使用Node-ffi
node-ffi是一个用于使用纯JavaScript加载和调用动态库的Node.js插件。它可以用来在不编写任何C ++代码的情况下创建与本地DLL库的绑定。同时它负责处理跨JavaScript和C的类型转换。
node-ffi
通过Buffer
类,在C代码和JS代码之间实现了内存共享,类型转换则是通过、、实现。由于node-ffi
/ref
包含C原生代码,所以安装需要配置Node原生插件编译环境。
C语言中有4种基础数据类型—-整型 浮点型 指针 聚合类型
整型、字符型都有分有符号和无符号两种。
ref
库中已经帮我们准备好了基础类型的对应关系。
字符型由char
构成,在GBK
编码中一个汉字占2个字节,在UTF-8中占用3~4个字节。一个ref.types.char
默认一字节。根据所需字符长度创建足够长的内存空间。这时候需要使用ref-array
库。
在传递中文字符型时,必须预先得知DLL
库的编码方式。node默认使用UTF-8编码。若DLL不为UTF-8编码则需要转码,推荐使用iconv-lite
*设置的返回值,通常返回的文本并不是定长,不会完全使用预分配的空间,末尾则会是无用的值。如果是预初始化的值,一般末尾是一大串的
0x00
,需要手动做trimEnd
,如果不是预初始化的值,则末尾不定值,需要C代码明确返回字符串数组的长度returnValueLength
。
ffi中内置了一些简写
只建议使用’string’。
字符串虽然在js中被认为是基本类型,但在C语言中是以对象的形式来表示的,所以被认为是引用类型。所以string其实是char* 而不是char
遇到定义为多维数组的基本类型 则需要使用ref-array进行创建
结构体是C中常用的类型,需要用到ref-struct
进行创建
指针是一个变量,其值为实际变量的地址,即内存位置的直接地址,有些类似于JS中的引用对象。
C语言中使用*
来代表指针
例如 int* a 则就是 整数型a变量的指针 , &
用于表示取地址
node-ffi
实现指针的原理是借助ref
,使用Buffer
类在C代码和JS代码之间实现了内存共享,让Buffer
成为了C语言当中的指针。
注意,一旦引用ref
,会修改Buffer
的prototype
,替换和注入一些方法,请参考文档
要明确一下两个概念 一个是结构类型,一个是指针类型,通过代码来说明。
// 申明一个类的实例
// 结构类型对应的指针类型
C的回调函数一般是用作入参传入。
// 根据结构体类型 开辟一个新的内存空间
// 开辟一个int 4字节内存空间
通常是传入的DLL路径错误,找不到Dll文件,推荐使用绝对路径。
如果是在x64的
node/electron
下引用32位的DLL,也会报这个错,反之亦然。要确保DLL要求的CPU架构和你的运行环境相同。
如果你的DLL是多个而且存在相互调用问题,会出现Dynamic Linking Error: Win32 error 126
错误3。这是由于默认的进程Path
是二进制文件所在目录,即node.exe/electron.exe
目录而不是DLL所在目录,导致找不到DLL同目录下的其他引用。可以通过如下方法解决:
实际node-ffi
调试的时候,很容易出现内存错误闪崩,甚至会出现断点导致崩溃的情况。这个是往往是因为非法内存访问造成,可以通过Windows
日志看到错误信息,但是相信我,那并没有什么用。C的内存差错是不是一件简单的事情。
winapi中,经常通过判断返回的pvoid
指针是否存在来判断是否成功,但是在node-ffi
中,对FFFFFFFF
的内存地址deref()
会造成程序闪崩。必须迂回采用指针的指针类型进行特判
WIN10
。如果你不是WIN10
用户,那么你只需要这一个工具即可,下面工具可以跳过。
ffi.Libary
时的所有IO请求和对应结果,查看缺少了什么DLL
。
tjfontaine大神提供了一个,可以根据头文件,自动生成node-ffi
函数申明,注意这个需要Linux
环境,简单用KOA包了一层改成了在线模式,可以丢到VPS中运行。
winapi存在大量的自定义的变量类型,waitingsong大侠的轮子 中完整翻译了全套windef.h
中的类型,而且这个项目采用TS来规定FFI的返回Interface,很值得借鉴。
注意!里面的类型不一定都是对的,相信作者也没有完整的测试过所有变量,实际使用中也遇到过里面类型错误的坑。
再运行项目,系统菜单就消失的无影无踪了。