napi-ffi 通过ffi 调用easytier-ffi c 库包
主要是一个简单试用,使用了napi-ffi 对于easytier ffi 包进行调用
包装代码
- 依赖
yarn add ffi-napi ref-napi ref-struct-di
- easytier.js
const ffi = require("ffi-napi");
const ref = require("ref-napi");
const Struct = require("ref-struct-di")(ref);
const path = require("path");
const platform = process.platform;
let libExt;
if (platform === "win32") {
libExt = ".dll";
} else if (platform === "darwin") {
libExt = ".dylib";
} else {
libExt = ".so";
}
const libPath = process.env.LIBEASYTIER || path.join(__dirname, "lib", `libeasytier_ffi${libExt}`);
const CString = ref.types.CString;
const Int32 = ref.types.int32;
const UintPtr = ref.types.uint64;
const CStringPtrPtr = ref.refType(CString);
const Void = ref.types.void;
const KeyValuePair = Struct({
key: CString,
value: CString,
});
const KeyValuePairPtr = ref.refType(KeyValuePair);
const libeasytier = ffi.Library(libPath, {
get_error_msg: [Void, [CStringPtrPtr]],
free_string: [Void, [CString]],
parse_config: [Int32, [CString]],
run_network_instance: [Int32, [CString]],
retain_network_instance: [Int32, [ref.refType(CString), UintPtr]],
collect_network_infos: [Int32, [KeyValuePairPtr, UintPtr]],
});
module.exports = {
...libeasytier
};
- 应用使用 app.yaml 是配置文件信息
instance_name = "xxxxxxxx"
instance_id = "xxxxx"
dhcp = true
listeners = [
"tcp://0.0.0.0:11010",
"udp://0.0.0.0:11010",
"wg://0.0.0.0:11011",
]
rpc_portal = "0.0.0.0:0"
[network_identity]
network_name = "xxxxx"
network_secret = "xxxxxx"
[[peer]]
uri = "tcp://xxxxxxx:11010"
[flags]
app.js
const fs = require('fs');
const conf = fs.readFileSync('./app.yaml', 'utf8');
const libeasytier = require("./easytier")
let result = libeasytier.run_network_instance(conf);
if (result === 0) {
console.log('Network instance started successfully.');
while (true) {
}
}
说明
通过napi-ffi 运行easytier-ffi 是一种方法,但是不是很好,推荐还是基于napi-rs 进行包装,直接使用预编译号的node 模块,这样维护以及性能会比较好,毕竟napi-ffi 这类的已经缺少维护,同时安装有一些依赖问题, 完整代码我已经提交github了可以查看
参考资料
https://github.com/node-ffi-napi/ref-napi