首页 > 编程语言 >使用Nodejs的addon导入cpp生成的dll时出现的问题记录

使用Nodejs的addon导入cpp生成的dll时出现的问题记录

时间:2023-09-06 15:57:19浏览次数:47  
标签:__ Nodejs dll bool DetectorInitialize cpp NXZ 1000

在使用Nodejs的addon导入自己编写的cpp的dll时出现的一系列问题记录

标签: __declspecNapiLoadLibraryAGetLastErrordumpbin /exports

正常创建一个使用Napi的nodejs addon项目(网上都有,在这里不赘述),主要代码如下:

#include <napi.h>
#include <iostream>
#include <atlstr.h>

#include "Static_Function.h"

using namespace std;

//定义调用函数签名模板
typedef bool (__stdcall *DetectorInitializeFun)( );
//例如表示返回值是bool,参数列表的两个 int
typedef bool (__stdcall *DetectorInitializeFun2)(int,int);

Napi::Boolean DetectorInitialize_test(const Napi::CallbackInfo &info){
    Napi::Env env = info.Env();
    //1、获取从js传入的参数(方便修改dll名称)
    string dllPath = info[0].As<Napi::String>();
    //2、通过LoadLibraryA载入(无法通过LoadLibrary,因为他的参数是字符串常量,而我的参数是从js传过来的)
    HINSTANCE hinstLib = LoadLibraryA(dllPath.c_str());
    DWORD error_id = GetLastError();
    cout << "(1)  dllPath:[" << dllPath << "]    hinstLib:[" << hinstLib << "]    error_id:[" << error_id << "]" << endl;
    if (hinstLib != NULL){
        //3、通过符号查找导出函数
        DetectorInitializeFun ProcAddress = (DetectorInitializeFun)GetProcAddress(hinstLib, "DetectorInitialize");
        error_id = GetLastError();
        cout << "(2)" << "    error_id:[" << error_id << "]" << endl;
        if (ProcAddress != NULL){
            cout << "(3)" << endl;
            //4、调用导出函数
            ProcAddress();
            //5、释放导入的库
            FreeLibrary(hinstLib);
            return Napi::Boolean::New(env, true);
        }
        FreeLibrary(hinstLib);
    }
    cout << "(4)" << endl;
    return Napi::Boolean::New(env, false);
}

Napi::Object Initialize(Napi::Env env, Napi::Object exports){
    exports.Set(Napi::String::New(env, "DetectorInitialize_test"), Napi::Function::New(env, DetectorInitialize_test));
    return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Initialize)

问题记录

  • 1、无法通过LoadlibraryA导入dll
cout << "(1)  dllPath:[" << dllPath << "]    hinstLib:[" << hinstLib << "]    error_id:[" << error_id << "]" << endl;

​ 输出结果是 (1) dllPath:[DllTest.dll] hinstLib:[00000000] error_id:[193]

(在这里不赘述路径不正确情况)

​ 通过查询原因是导入的DllTest.dll是64位,而当前项目是32位(当前nodejs是32位),解决办法:重新将dll编译为32位,或者切换nodejs为64位(注:切换之后需要重新npm install,保证你的node_modules都变成了64位)

.

.

  • 2、成功载入DllTest_x86.dll,但是无法调用内部方法

​ 可以看到我的代码中是这样调用的

DetectorInitializeFun ProcAddress = (DetectorInitializeFun)GetProcAddress(hinstLib, "DetectorInitialize");

​ 通过查阅相关资料,需要使用dumpbin /exports TestDll_x86.dll查询dll导出的符号表,使用符号进行调用,而不是导出的函数名称

​ 通过dumpbin,得到结果如下

Microsoft (R) COFF/PE Dumper Version 14.36.32532.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file .\DllTest_x86.dll

File Type: DLL

  Section contains the following exports for DllTest.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 000111F9 ?DetectorInitialize@@YA_NXZ = @ILT+500(?DetectorInitialize@@YA_NXZ)

  Summary

        1000 .00cfg
        1000 .data
        1000 .idata
        1000 .msvcjmc
        3000 .rdata
        1000 .reloc
        1000 .rsrc
        8000 .text
       10000 .textbss

​ 会发现其中一段0 000111F9 ?DetectorInitialize@@YA_NXZ = @ILT+500(?DetectorInitialize@@YA_NXZ),这就是被导出的符号列表,只有这个,才代表你的dll导出了函数供你调用,符号是 ?DetectorInitialize@@YA_NXZ,需要把代码改成:

DetectorInitializeFun ProcAddress = (DetectorInitializeFun)GetProcAddress(hinstLib, "?DetectorInitialize@@YA_NXZ");

​ 最后在下面通过ProcAddress();调用即可。

.

.

  • 3、如何定义导入的函数签名与编写具备导出性质的dll

    • 通过下面方式定义函数签名,用来表示导入的函数模板
    //例如表示返回值是bool,参数列表的两个int
    typedef bool (__stdcall *DetectorInitializeFun2)(int,int);
    
    • 通过如下方式可以定义导出dll的函数

    下面的代码是visual studio自动生成的dll项目的头文件,需要在函数声明前使用__declspec(dllexport)来表示导出函数

    #ifndef PCH_H
    #define PCH_H
    
    // 添加要在此处预编译的标头
    #include "framework.h"
    
    #ifdef DETECTOR_EXPORTS
    #define DETECTOR_API __declspec(dllexport)
    #else
    #define DETECTOR_API __declspec(dllimport)
    #endif
    
    
    DETECTOR_API bool DetectorInitialize();
    
    #endif //PCH_H
    

    实际上不需要按照上面的DETECTOR_API bool DetectorInitialize();来定义,可以用__declspec(dllexport)bool DetectorInitialize();来定义。之所以使用宏定义是为了方便管理,而不用到处都是__declspec(dllexport)。然后函数正常在.cpp文件实现即可。

标签:__,Nodejs,dll,bool,DetectorInitialize,cpp,NXZ,1000
From: https://www.cnblogs.com/MCMonkey/p/17682498.html

相关文章

  • 【原创】基于QT编写的支持IPv4/IPv6双协议栈,TCP/UDP双模式,DLL内存加载的模块化远控木
    本人已经本科毕业一年有余,在平常实习过程中,发现大佬都对我的本科毕设--双协议栈远控木马感兴趣。据我所知,目前流行的C2远控软件中,MSF支持IPv4和IPv6,但是MSF生成的单个木马只是支持其中的一种协议,而不是双协议栈。CobaltStrike目前尚无IPv6的使用案例。其他支持双协议栈的C2软件......
  • C++中模块(DLL)对外暴露接口的几种方式
    函数导出:通过在函数前面加上导出修饰符(如__declspec(dllexport))来导出函数。优点是简单易用,缺点是无法避免函数名冲突,且需要手动导出每个函数。.def文件:通过定义一个.def文件,在其中指定要导出的函数名和入口点。优点是可以一次性导出多个函数,缺点是需要额外的.def文件,且与代码分......
  • ZLMeidaKit在Windows上启动时:计算机中丢失MSVCR110.dll,以及rtmp推流后无法转换为flv
    场景ZLMediaKit在Windows上实现Rtmp流媒体服务器以及模拟rtmp推流和http-flv拉流播放:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130221608按照以上教程启动MediaServer.exe时提示:无法启动此程序,因为计算机中缺失MSVCR110.dll,尝试重新安装程序以解决此问题......
  • 自留_CPP面向对象习题
    Question第一部分C++面向对象练习题1定义盒子类Box,包括三个private类型数据成员x,y,z,分别代表其长、宽、高。类中包括有参构造函数,计算体积的private类型成员函数volume和public类型显示函数display。在主函数中,定义对象box1(10,20,30),调用相关函数显示该盒子对象的长、宽、高......
  • nodejs + superagent 示例记录【2023-09-02】【尝试nodejs接口测试库】
    constsuperagent=require("superagent");(async()=>{ try{  constres=awaitsuperagent.get(   "https://jsonplaceholder.typicode.com/users"  );  constheaderDate=   res.headers&&res.headers.date?......
  • JSONCPP向浏览器前端发送服务器本地文件列表
    服务器解析了浏览器请求之后,要进行响应响应体里需要存放请求的内容HTML标签:是页面的核心内容,定义了页面有什么内容。CSS:控制HTML元素的排版布局和展示方式,是美化页面文档的。JavaScript:让用户与页面进行交互,或在网页背后默默操控网页,以便让显示的内容与效果有所改变。对网页来......
  • 记Nodejs的简单笔记
    Nodejs简单笔记fs模块VSCode路径提示插件-PathAutocomplete1.读取文件constfs=require('fs');fs.readFile('demo.txt','UTF-8',function(error,data){if(error==null){//文件读取成功console.log('data:'+da......
  • 【Azure App Service for Linux】NodeJS镜像应用启动失败,遇见 RangeError: Incorrect
    问题描述在AppServiceForLinux中,部署NodeJS应用,应用启动失败。报错信息为:2023-08-29T11:21:36.329731566ZRangeError:Incorrectlocaleinformationprovided2023-08-29T11:21:36.329776866ZatIntl.getCanonicalLocales(<anonymous>)2023-08-29T11:21:36.329783066ZatC......
  • 【Azure App Service for Linux】NodeJS镜像应用启动失败,遇见 RangeError: Incorrect
    问题描述在AppServiceForLinux中,部署NodeJS应用,应用启动失败。报错信息为:2023-08-29T11:21:36.329731566ZRangeError:Incorrectlocaleinformationprovided2023-08-29T11:21:36.329776866ZatIntl.getCanonicalLocales(<anonymous>)2023-08-29T11:21:36.3297830......
  • PyQt/PySide's qwindows.dll qwindowsvistastyle.dll is corrupted by UPX
    Windows1064-bitsPython3.8.1064-bitsPySide25.15.2PyInstaller4.3UPX4.1.0itraises:"ThisapplicationfailedtostartbecausenoQtplatformplugincouldbeinitialize"Solutioninspecfiles,addupx_exclude=['qwindows.dll'......