node-ffi调用dll文件的那些坑

分享,记录,科技 2018-02-22 12 条评论 访问: 38,818 次

项目中要调用dll文件,dll的全称是Dynamic Link Library,动态链接库,windows为了减少文件体积提高函数库的复用率而使用。有些基础功能应该用公共函数库来实现,让每个程序自己实现是很荒谬的。dll和exe一样,只是没有入口点。用windows下面的rundll32可以直接运行dll文件中的函数,所以有时候中病毒可能在电脑里看到rundll32进程。打包成dll文件可以避免暴露源码。本文简述在nodejs中调用dll文件。

需要几个库ref,ffi,其中ffi的安装十分繁琐,有几点注意事项
安装VC++ Build Tools,可从微软官网下载。传送门
下载Python2.x版本,不支持Python3。传送门
看好dll文件是32位还是64位,32位的要用32位的node,64位的要用64位的node,否则会出错。传送门
然后windows调用不了.so,同理linux也调用不了dll。
ref库让js的Buffer拥有指针的特性。简单介绍下。

分配一个字符串的内存空间,都是动态的,具体多少字节不用管
let strPtr = ref.alloc('CString')
strPtr.deref()可以得到字符串的内容
typeof strPtr === object
typeof strPtr.deref() === string

ref.types.TYPE
let object = ref.types.void
objectPtr是一个void*类型的Buffer
let objectPtr = ref.refType(object)
一般不知道对象结构是啥的时候就用void*
ffi的使用主要是ffi.Library

let lib = new ffi.Library({
  'init': ['void*', ['void**', 'string', 'string', 'string']],
})

char*可以直接在参数列表写成string,这样传递这个参数的时候直接这样'some string'传递即可,就不必再ref.alloc('CString', 'some string')

如果参数是函数指针类型就直接写pointer
'SetRecvMsgCallBack': ['int', ['void*', 'pointer']]

let sync_msg_cb = ffi.Callback('int', ['void*', 'string'],
    function (p, str) {
      console.log('callback')
      console.log(str)
    })

调用的时候就直接lib.SetRecvMsgCallBack(objectPtr, sync_msg_cb)
通过指针返回值,可以ref.alloc一个变量,然后传进去。函数执行后就有数据了,deref可以看到数据


除非注明,嗯VIEW文章均为原创,转载请以链接形式标明本文地址
本文地址:https://www.umview.com/trouble-shooting-on-node-ffi

本文由 Mark 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

12 条评论

  1. 萌新菜鸟
    萌新菜鸟

    使用ffi实现海康威视摄像头的开发是真的难受,资料太少了

  2. 拉偶奥
    拉偶奥

    博主你好, 关于node-ffi调用dll的个别问题请教,希望能得到您的指点, 联系QQ:78282385

  3. 深航空少
    深航空少

    写了一个dlltest.js文件用来加载dlltest.dll动态库,代码如下:
    const ffi = require('ffi');
    exports.Dlltest = ffi.Library('dlltest', {

    'ShowWelcome' : ['void', []],

    });
    利用electron打包成.exe在windows平台下成功运行,但是关闭之后,进程还在后台驻留。
    我尝试了不加载dll,直接用electron打包成exe的方式,关闭之后,正常退出。
    从而定位出,是因为通过node-ffi引入了dll之后,在.exe关闭时,没有正常释放dll,造成内存泄漏,使得程序不能完全退出。
    想问下,如何释放通过ffi模块加载的dll啊?
    Any response will be highly appreciated~

    1. Mark
      Mark

      我没注意过这个情况。。= =

  4. 大佬手赚网
    大佬手赚网

    感觉好久没更新了呢,是不是博主最近学业繁忙呢,比较喜欢博主写的东西,同作为大学生,很有亲切感!

    1. Mark
      Mark

      最近十分繁忙

  5. SEO外链
    SEO外链

    迎春花一开,引得百花竞放,梅花开,杏花开,桃花开,看的人眼花,花多的你都叫不上名字,番正都是花,看起来很好看,很映人的眼,很牵动人的心,能激发人多情,能触动人去联想,给人感觉是北京成了花的海洋,花的世界,花的天下,花的花境。冬天的护城河畔,虽然没有花,但是一河青冰也装饰的护城河银装素裹,玉带环绕,更是富有生活的特写。

  6. 老陈网志
    老陈网志

    好久没来你的博客逛了。

  7. 大佬手赚网
    大佬手赚网

    这是真的很厉害了,看不太懂,吓得我赶紧拿起了C语言的书看了看!

  8. 菜鸟头头
    菜鸟头头

    说实话,一般技术文章很少有人评论。真滴,看到技术东西都想直接差掉。哈哈哈哈

  9. 大佬手赚网
    大佬手赚网

    好厉害,对于一个连数学都学不好的的人,这个真的是看不太懂!

  10. 姜辰
    姜辰

    踩过了就好,至少以后不会遇到了。233

添加新评论