今天和大家聊一聊如何在JavaScript中调用C++动态链接库


什么是ffi

ffi 是Foreign Function Interface的简称,是一款nodejs的addon。

可以让大家在nodejs中调用c风格的c++动态链接库

ffi调用起来非常简单,可以看下官网的这个例子

var ffi = require('ffi-napi');

var libm = ffi.Library('libm', {
  'ceil': [ 'double', [ 'double' ] ]
});
libm.ceil(1.5); // 2

// You can also access just functions in the current process by passing a null
var current = ffi.Library(null, {
  'atoi': [ 'int', [ 'string' ] ]
});
current.atoi('1234'); // 1234

只要传入dll的路径,方法名称,返回值和参数类型,就可以得到一个关于dll中对应方法的代理对象。

接着在这个代理对象上执行对应的方法即可。

ffi原理

node-ffi的原理可以参见下图

image-20200614103706835

实际上node-ffi是在libffi之上套了一层壳,将libffi的方法封装成了nodejs的addon

而libffi又调用了系统的API,打开特定的dll(POSIX下dlopen方法/Winodws下LoadLibraryEx方法),并获取对应的方法的地址(POSIX下dlsym方法/Winodws下GetProcAddress方法)。

获得方法对象之后,就可以封装对应的参数,在dll中执行,并获得对应的返回值

image-20200614104828236

ffi问题

ffi相较于单独编写nodeaddon的方式简便了不少。

但是也会存在一定的问题。

  • ffi只支持c风格的dll
  • ffi通过对应的字符串进行动态加载,没有编译优化,相较于addon会有一定性能损失

因此ffi也不是银弹,需要大家在项目中根据实际情况进行考虑


参考文档:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E5%A6%82%E4%BD%95%E5%9C%A8JavaScript%E4%B8%AD%E8%B0%83%E7%94%A8C++%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系