Visual c++ 链接到同一DLL两次-同时隐式和显式

Visual c++ 链接到同一DLL两次-同时隐式和显式,visual-c++,dll,static-linking,dynamic-linking,loadlibrary,Visual C++,Dll,Static Linking,Dynamic Linking,Loadlibrary,我正在处理的项目将加载同一个库两次: 使用LoadLibrary 静态加载带有lib文件和“u declspec(dllimport/dllexport)”的DLL 在这种情况下发生了什么?这两个“加载”是否使用相同的堆或共享其他内容。例如,它是否与调用LoadLibrary两次相同或相似 我的一般问题是,当通过第二种方法从exe调用dll方法时,我遇到了堆栈损坏问题。我想知道问题是不是因为第一次装载?所有项目都使用相同的RT、对齐方式等。通过“使用lib文件和_declspec(dllimpo

我正在处理的项目将加载同一个库两次:

  • 使用LoadLibrary
  • 静态加载带有lib文件和“u declspec(dllimport/dllexport)”的DLL
  • 在这种情况下发生了什么?这两个“加载”是否使用相同的堆或共享其他内容。例如,它是否与调用LoadLibrary两次相同或相似

    我的一般问题是,当通过第二种方法从exe调用dll方法时,我遇到了堆栈损坏问题。我想知道问题是不是因为第一次装载?所有项目都使用相同的RT、对齐方式等。

    通过“使用lib文件和_declspec(dllimport/dllexport)静态加载DLL”,我假定您的意思是编译可执行文件时使用.lib作为依赖项,并且在运行时.DLL由exe自动加载(在开始处)。以下是一段来自:

    系统为每个加载的模块维护每个进程的参考计数。由于加载时动态链接而在进程初始化时加载的模块的引用计数为1。每次调用LoadLibrary加载模块时,模块的引用计数都会增加。调用LoadLibraryEx也会增加引用计数,除非第一次加载模块并将其作为数据或图像文件加载

    换句话说,在应用程序启动时加载.dll(因为您针对它进行了链接),并且只增加其ref count()。有关更多信息,您也可以查看,或

    绝对没有理由在同一个应用程序中对同一个.dll使用这两种方法

    第二种方法是首选方法,如果.dll附带一个.h文件(保存库导出的函数定义,编译时需要)和一个.lib文件(指示喜欢的人将.dll文件中的引用添加到可执行文件中)

    另一方面,第一种方法是唯一的方法,如果您只有.dll文件,并且您不知何故拥有它导出的函数的签名。在这种情况下,您必须在应用程序中定义指向这些函数的指针,并使用
    GetProcAddress
    初始化它们。在某些情况下,这种方法是首选的,例如,当.dll中的功能仅在程序流的某个角落需要时,在这种情况下,如果99%的情况下不需要,则没有必要链接.lib文件并在应用程序启动时加载.dll。此外,这种方法的一个主要优点是:如果以某种方式删除了.dll,那么只有与之相关的功能将无法工作(
    LoadLibrary
    将失败),而使用另一种方法时,应用程序将无法启动

    现在,没有细节,我无法弄清你遇到的具体问题。您说您“正常”(根据.h文件中的定义)调用一个函数,它会失败,而如果您使用函数指针调用它(使用相同的参数),它会成功吗?堆栈错误消息是什么

    注意:根据我的经验,在这种情况下,堆栈损坏的一个典型原因是调用方和被调用方之间的调用约定不匹配(stdcallvscdecl或反之亦然)。混合调试和发布也可能会带来问题。

    通过“使用lib文件静态加载DLL和_declspec(dllimport/dllexport)”,我假定您的意思是您使用.lib作为依赖项编译了可执行文件,并且在运行时.DLL由exe自动加载(在开始处)。以下是一段来自:

    系统为每个加载的模块维护每个进程的参考计数。由于加载时动态链接而在进程初始化时加载的模块的引用计数为1。每次调用LoadLibrary加载模块时,模块的引用计数都会增加。调用LoadLibraryEx也会增加引用计数,除非第一次加载模块并将其作为数据或图像文件加载

    换句话说,在应用程序启动时加载.dll(因为您针对它进行了链接),并且只增加其ref count()。有关更多信息,您也可以查看,或

    绝对没有理由在同一个应用程序中对同一个.dll使用这两种方法

    第二种方法是首选方法,如果.dll附带一个.h文件(保存库导出的函数定义,编译时需要)和一个.lib文件(指示喜欢的人将.dll文件中的引用添加到可执行文件中)

    另一方面,第一种方法是唯一的方法,如果您只有.dll文件,并且您不知何故拥有它导出的函数的签名。在这种情况下,您必须在应用程序中定义指向这些函数的指针,并使用
    GetProcAddress
    初始化它们。在某些情况下,这种方法是首选的,例如,当.dll中的功能仅在程序流的某个角落需要时,在这种情况下,如果99%的情况下不需要,则没有必要链接.lib文件并在应用程序启动时加载.dll。此外,这种方法的一个主要优点是:如果以某种方式删除了.dll,那么只有与之相关的功能将无法工作(
    LoadLibrary
    将失败),而使用另一种方法时,应用程序将无法启动

    现在,没有细节,我无法弄清你遇到的具体问题。您说您“正常”(根据.h文件中的定义)调用一个函数,它会失败,而如果您使用函数指针调用它(使用相同的参数),它会成功吗?堆栈错误消息是什么

    注意:根据我的经验,在这种情况下,堆栈损坏的一个典型原因是调用