V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yangheng4922
V2EX  ›  Node.js

Nodejs 使用 node-ffi 调用 DLL 的操作

  •  
  •   yangheng4922 · 2020-07-19 01:04:39 +08:00 · 2730 次点击
    这是一个创建于 1368 天前的主题,其中的信息可能已经有所发展或是发生改变。

    node 需要使用一个原生模块 折腾了好久

    环境什么的搞了大半天 弄好了

    可以调用 DLL 的方法 运行

    但是发现 有一个 DLL 暴露的是一个 Class 不知道要怎么调用

    今天查了好久资料

    正常导出方法的 DLL 头文件是这样的

    extern "C" int __declspec(dllexport)My_Test(char *a, int b, int c);
    extern "C" void __declspec(dllexport)My_Hello(char *a, int b, int c);
    

    nodejs 的调用方法

    const dll = ffi.Library( './test.dll', {
        // My_Test 是 dll 中定义的函数,两者名称需要一致
        // [a, [b,c....]] a 是函数出参类型,[b,c]是 dll 函数的入参类型
        My_Test: ['int', ['string', 'int', 'int']], // 可以用文本表示类型
        My_Hello: [ref.types.void, ['string', ref.types.int, ref.types.int]] // 更推荐用`ref.types.xx`表示类型,方便类型检查,`char*`的特殊缩写下文会说明
    })
    

    但是我哪一个模块导出的是一个 class 不知道要怎么去调用它

    class __declspec(dllexport) Person

    #pragma once 
    
    class  __declspec(dllexport) Person
    {
    private:
    	int age;
    public:
    	int getAge();
    	void setAge(int a);
    };
    
    9 条回复    2020-07-20 20:08:08 +08:00
    ysc3839
        1
    ysc3839  
       2020-07-19 01:38:23 +08:00 via Android
    没办法调用,因为 C++ 没有一个统一的 ABI,不同编译器编译出来的都不能互相调用,甚至同一个编译器不同版本也不一定兼容。
    解决方法是用 C 语言的接口封装一遍。比如 cef https://bitbucket.org/chromiumembedded/cef 就是这么做的。
    VDimos
        2
    VDimos  
       2020-07-19 04:10:46 +08:00 via Android
    你是想导出这个类来给 node 使用?
    编译成 DLL 之后,类这个概念已经不存在了。
    FFI 是用来调用函数的,在 linux 就是用了 dlopen 和 dlsym 这些封装的,win 下提供了类似的函数,它们本质上都是在 so 或者 dll 文件里查找动态符号表,所以你想要使用这个类,只有再导出一个 c 标准的函数,然后在这个函数里实现你想做的要用到这个类的操作。
    yangheng4922
        3
    yangheng4922  
    OP
       2020-07-19 12:10:18 +08:00
    @ysc3839 #1
    @VDimos #2
    意思是没办法调用 C++的类 需要运行的话只能让 C++程序员封装层函数来调用么
    yangheng4922
        4
    yangheng4922  
    OP
       2020-07-19 12:12:23 +08:00
    @VDimos #2 不是我想导出类 这个 DLL 是公司 c++发给我调试的
    VDimos
        5
    VDimos  
       2020-07-19 16:40:30 +08:00 via Android
    @yangheng4922 是的,类是 cpp 的概念,dll 里面只有函数的概念了
    VDimos
        6
    VDimos  
       2020-07-19 16:50:52 +08:00 via Android
    @yangheng4922 你可以自己写,msdn 上说用_declspec(dllimport)可以调用这个导出的对象,前提是你们编译器这些得一样。你可以通过 pe 工具查看它用的编译器这些,我记得 dll 是有这个信息的。然后自己用 extern “c”来导出 c 风格的函数。
    yangheng4922
        7
    yangheng4922  
    OP
       2020-07-19 18:55:16 +08:00
    @VDimos #6 不会 C++
    ysc3839
        8
    ysc3839  
       2020-07-19 19:26:20 +08:00 via Android
    @yangheng4922 是的。
    bestie
        9
    bestie  
       2020-07-20 20:08:08 +08:00
    我之前也有这么个需求,后来直接让 C++提供 node 模块了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1172 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:18 · PVG 02:18 · LAX 11:18 · JFK 14:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.