本文基于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}},
description:{{item.description}},
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>
结果
…