gpt4 book ai didi

c++ - DLL 中的 SetDllDirectory LoadLibrary

转载 作者:行者123 更新时间:2023-11-28 00:26:05 32 4
gpt4 key购买 nike

我可以在 C++ DLL 中使用 C++ SetDllDirectoryLoadLibrary 命令来加载另一个 DLL 吗?我试过像这样使用它们:

可执行文件调用第一个 DLL,然后第一个 DLL 加载第二个 DLL,然后第二个 DLL 进行计算...

但是当我运行可执行文件时,我收到此错误消息:

This application has requested the Runtime to terminate it in an unusual way. Please contact the applications support team for more information.

当直接链接到可执行文件时,第二个 DLL 工作正常!

这是我的可执行文件中的代码:

#include <windows.h>
#include <iostream>

int main(){
HINSTANCE hDLL_Link=NULL;
SetDllDirectory((LPCWSTR)L"C:\\Users\\MC\\Documents\\2014_07_01a_FDD_VC2008\\test_call_DLL\\EXE_calls_Link_DLL\\Release");
hDLL_Link=LoadLibrary((LPCWSTR)L"Link_DLL.dll");
if(hDLL_Link==NULL) std::cout<<"did not load"<<'\n';
typedef void (*Ptr_OPS_Link)();
Ptr_OPS_Link Ptr_OPS_Link_0;
Ptr_OPS_Link_0=(Ptr_OPS_Link)GetProcAddress(hDLL_Link,"OPS_Link");
Ptr_OPS_Link_0();
FreeLibrary(hDLL_Link);
system("pause");
}

这是第一个 DLL 中的代码:

#include "Link.h"

extern "C" __declspec(dllexport)
void OPS_Link(){
Link*Link_Ptr_Object=NULL;
if(Link_Ptr_Object==NULL){
Link_Ptr_Object=new Link();
}
if(Link_Ptr_Object==NULL){
//can not throw inside __declspec(dllexport) functions marked extern "C" that's why std::cout is implemented:
std::cout<<"Error: could not link to FDD DLL"<<'\n';
system("pause");
}
delete Link_Ptr_Object;
Link_Ptr_Object=NULL;
}

Link::Link()
:m_void_Ptr_ObjectByDLL(NULL){
HINSTANCE hDLL=NULL;//handle to DLL
SetDllDirectory((LPCWSTR)L"C:\\Software\\Octave-3.6.1\\bin\\");
hDLL=LoadLibrary((LPCWSTR)L"C:\\Users\\MC\\Documents\\2014_07_01a_FDD_VC2008\\Executable\\Release\\FDD_DLL.dll");
if(hDLL==NULL){
throw "DLL loading could not be done";
}else if(hDLL!=NULL){
typedef void (*Ptr_OPS_FDD)(std::string, int, int);
Ptr_OPS_FDD Ptr_OPS_FDD_0;//pointer to procedure inside DLL
Ptr_OPS_FDD_0=NULL;
Ptr_OPS_FDD_0=(Ptr_OPS_FDD)GetProcAddress(hDLL,"OPS_FDD");
if(Ptr_OPS_FDD_0==NULL){
FreeLibrary(hDLL);
throw "DLL exported function address could not be determined";
}else{
//run the procedure inside DLL:
Ptr_OPS_FDD_0("FDD_INPUT_Truss_Bridge_Data2_Ambient_Inch_11Channels_77824Samples_SamplingFreq_256Hz.txt",11,256);//LabScaleTruss
//Ptr_OPS_FDD_0("FDD_INPUT_Ambient_EW_15Channels_3000Samples_SamplingFreq_20Hz.txt",15,20);//AmbientEW
//Ptr_OPS_FDD_0("FDD_INPUT_Meriden_3Channels(3_5_8)_3686400Samples_SamplingFreq_2048Hz.txt",3,2048);//MeridenBridge
FreeLibrary(hDLL);
}
}
}

最佳答案

您的代码中有几件事可能会导致失败:

  1. 如果无法加载 DLL,则不退出:
  2. 您正在传递内部使用动态分配的对象,因此将使用堆管理器。

对于上面的 1.,您的 main() 函数仅在找不到库时执行简单的 cout。然而,main 函数并没有退出,而是像找到了库一样继续运行。

对于上面的 2.,将 std::string 作为参数传递给 DLL 函数很容易出错,除非您确切地知道 你在做什么。它容易出错的原因是

  • 包含函数调用的 DLL 可能是使用与调用函数的 DLL 不同的一组选项构建的。这些不同的选项可能会导致 std::string 的实现方式、它在内存中的布局方式等方面的差异。

  • 包含函数调用的 DLL 可能是由与调用函数的 DLL 不同的编译器版本构建的。同样,std::string

  • 的不同实现也存在同样的问题
  • 使用 std::string 的 DLL 和模块可能不是使用 C 运行时库的 DLL 版本 构建的。如果未使用 DLL 版本的运行时库构建和链接 DLL/模块,则 DLL 将使用与模块不同的堆。由于使用了不同的内存堆,对 std::string 的任何操作都将无效。

所以简而言之,除非你能保证

  1. 您正在使用完全相同版本的编译器和编译器选项构建模块和 DLL。
  2. 您正在将所有模块链接到运行时库的 DLL 版本。

然后将 std::string 作为参数传递,并且通常,传递维护动态分配内存的任何对象,可能会或将会导致运行时错误。

关于c++ - DLL 中的 SetDllDirectory LoadLibrary,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24999520/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com