Electron中JS调用DLL:ffi-napi的简单例子

本文基于Electron11+Vue+ffi-napi环境下进行实验


DLL包含的接口以及数据结构

本文调用的dll为C语言编写

dll头文件:

...
//用到的数据结构
typedef struct test {
	char name[128];
	char description[512];
	int num;
}Test;
//接口函数
extern "C" {
	DLL_TYPE int returnANumber();
	DLL_TYPE int add_int(int a, int b);
	DLL_TYPE float add_float(float a, float b);
	DLL_TYPE double add_double(double a, double b);
	DLL_TYPE char returnAChar();
	DLL_TYPE void strUpr(char* str,int len);//返回hahah
	DLL_TYPE void strAdd(const char *a, const char *b, char* target);
	DLL_TYPE void getAStruct(Test* sptr);
	DLL_TYPE void getStructArray(Test* sptr, int len);
}

使用ffi-napi 调用Dll

JS文件:

const ffi = require('ffi-napi')
const ref = require('ref-napi')
const refArray = require('ref-array-napi')
const Struct = require('ref-struct-napi')

const test = Struct({
  name:refArray(ref.types.char,128),
  description:refArray(ref.types.char,512),
  num:ref.types.int
})

const StructArray = refArray(test)

const dll = ffi.Library('../resources/test.dll', {
  returnANumber: [ref.types.int, []],
  add_int: [ref.types.int, [ref.types.int, ref.types.int]],
  add_float: [ref.types.float, [ref.types.float, ref.types.float]],
  add_double: [ref.types.double, [ref.types.double, ref.types.double]],
  returnAChar: [ref.types.char, []],
  strAdd: [ref.types.void, ['string', 'string','char*']],
  strUpr:[ref.types.void,['char*','int']],
  getAStruct:[ref.types.void,[ref.refType(test)]],
  getStructArray:[ref.types.void,[StructArray,ref.types.int]],
})

module.exports = {
  returnANumber() {
    return dll.returnANumber();
  },
  add_int(a, b) {
    return dll.add_int(a, b);
  },
  add_float(a, b) {
    return dll.add_float(a, b);
  },
  add_double(a, b) {
    return dll.add_double(a, b);
  },
  returnAChar() {
    return dll.returnAChar();
  },
  strAdd(a, b) {
    let str = ref.allocCString("")
    dll.strAdd(a, b,str)
    return ref.readCString(str)
  },
  strUpr(s,len){
    let str = ref.allocCString(s)
    dll.strUpr(str,len)
    return ref.readCString(str)
  },
  getAStruct(){
    let res = new test()
    dll.getAStruct(res.ref())
    return toStruct(res)
  },
  getStructArray(){
    let res = new StructArray(100)
    dll.getStructArray(res,100)
    return toStructArray(res)
  }
}

function toStruct(stru){
  return {name:ref.readCString(stru.name.buffer),
    description:ref.readCString(stru.description.buffer),
    num:stru.num}
}

function toStructArray(struarray){
  let len = struarray.length
  let array = new Array(len)
  for(let i=0;i<len;i++){
    array[i] = toStruct(struarray[i])
  }
  return array
}

调用结果展示

<template>
  <div class="hello">
    <p>returnANumber:{{ num }}</p>
    <p>add_int:{{ inum }}</p>
    <p>add_float:{{ fnum }}</p>
    <p>add_double:{{ dnum }}</p>
    <p>returnAChar:{{ char }}|{{ String.fromCharCode(char) }}</p>
    <p>strAdd:{{ str }}</p>
    <p>strUpr:{{ sstr }}</p>
    <p>getAStruct:{{ stru.name }}</p>
    <p>getStructArray:</p>
    <ol>
      <li v-for="(item,i) in struarray" :key="i">name:{{item.name}},&nbsp;&nbsp;&nbsp;
        description:{{item.description}},&nbsp;&nbsp;&nbsp;
        num:{{item.num}}</li>
    </ol>
  </div>
</template>

<script>
import {
  returnANumber,
  add_int,
  add_float,
  add_double,
  returnAChar,
  strAdd,
  strUpr,
  getAStruct,
  getStructArray,
} from "../dlltest.js";
export default {
  name: "HelloWorld",
  data() {
    return {
      num: returnANumber(),
      inum: add_int(1, 2),
      fnum: add_float(3, 4),
      dnum: add_double(5, 6),
      char: returnAChar(),
      str: strAdd("Hello", "World"),
      sstr: strUpr("hahaha", 7),
      stru: getAStruct(),
      struarray: getStructArray(),
    };
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

结果

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值