如何在JavaScript中调用C++动态链接库

今天和大家聊一聊如何在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的原理可以参见下图

如何在JavaScript中调用C++动态链接库_第1张图片

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

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

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

如何在JavaScript中调用C++动态链接库_第2张图片

ffi问题

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

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

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

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


参考文档:

  • node-ffi使用指南 - 掘金
  • ffi - npm
  • LuaJIT FFI 介绍,及其在 OpenResty 中的应用(上) - spacewander - SegmentFault 思否
  • Node-FFI 不得不说的原理 - Dosk技术站
  • libffi
  • LoadLibraryExA function (libloaderapi.h) - Win32 apps -Microsoft Docs
  • GetProcAddress function (libloaderapi.h) - Win32 apps - Microsoft Docs

本文会经常更新,请阅读个人博客原文: https://xinyuehtx.github.io/ ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

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

你可能感兴趣的:(前端,nodejs,JavaScript)