node-ffi 调用Golang动态库

本文介绍如何使用node-ffi库调用Golang动态库,包括跨平台加载DLL/SO文件、异步加载及类型转换注意事项,避免因类型错误导致的程序崩溃。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

node-ffi 调用Golang动态库

node-ffi库以及无维护,尝试使用napi-ffi

const ffi = require('ffi-napi');
const fs = require('fs');
console.log(process.arch, process.platform);

//# 坑 不能使用除开dll其他的后缀
export class AA {
    static dll;

    //這個加載太耗時了,这种不是IO,是CPU,所以只等API支持异步
    static async load(df) {
        return new Promise((resolve, reject) => {
            if (!fs.existsSync(df)) {
                reject('dll no exist');
                return;
            }
            const t = Date.now();
            console.log('Load Start', t);
            this.dll = ffi.Library(df, {
                'initAABot': ['void', ['string', 'bool']],//类型是go String
                // 'initDefault': ['void', []],
                'runAABot': ['void', ['bool']],
                'exitAABot': ['void', []],
            });
            console.log('Load Finish:', Date.now() - t, 'ms');
            resolve();
        });

    }

    static iniAABot(port) {
        if (!this.dll) return null;
        return this.dll.initAaBot(port, true);
    }

    //启动
    static runAABot() {
        if (!this.dll) return null;
        const _self = this;
        return _self.dll.runAABot(true);
    }

    //关闭,关闭后指挥关闭AA资源,不可再次进行开启
    static exitAABot() {
        if (!this.dll) return null;
        const _self = this;
        return _self.dll.exitAABot();
    }

    static getAAName() {
        //if (process.arch)
        if (process.platform === 'win32') {
            return 'AA.dll';
        }
        if (process.platform === 'darwin') {
            return 'AA.so';
        }
        return '';
    }
}

golang export 部分

//export initDefault
func initDefault() {
    initBot(":20011", true)
}

//export initAABot
func initAABot(p *C.char, color bool) {
    port := C.GoString((*C.char)(p))
    initBot(port, color)
}

//export runAABot
func runAABot(async bool) {
    if bot != nil {
        return
    }
    if async {
        go startBot() //异步启动
    } else {
        startBot()
    }
}

//export exitAABot
func exitAABot() {
    if bot != nil {
        bot.Close()
    }
}

func initBot(port string, color bool) {
    config.Runner = true
    config.Color = color
    config.ServerPort = port
}

注意

需要注意的是数据类型,如果node调用的时候数据类型传入有误,可能会导致dll雪崩,调用不报错但是运行会崩溃。比如说node string,那么在golang export 中就可以用 *char 来表示

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值