gpt4 book ai didi

C++ LoadLibrary 抛出 First-Chance Exception,但有效吗?

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

我完成了我的小应用程序,我正在努力确保我没有内存泄漏和错误。查看我的输出后,我注意到我的一个函数抛出了 First-Chance 异常,但该函数运行良好并且没有崩溃。

该函数调用 CLR C++ DLL 中的另一个函数。我只是为了测试而删除了 DLL 函数中的几乎所有代码,但仍然抛出异常,所以我知道问题出在我的 EXE 函数上。

这是EXE函数调用DLL函数的代码。

LPCTSTR CHAXC0RDlg::Encrypt(LPCTSTR strValue)
{
const char* Return;
HINSTANCE hDLL = LoadLibrary(L"Library.dll");

if(hDLL)
{
FARPROC hMethod = GetProcAddress(HMODULE (hDLL), "Encrypt");

if(hMethod)
{
typedef const char* (*FunctionSig)(LPCTSTR);
FunctionSig MethodCall = FunctionSig(hMethod);

Return = MethodCall(strValue);
FreeLibrary(hDLL);
}
}

return _tcsdup(CString(Return));
}

这是 DLL 函数(如您所见,我删除了所有代码,除了生成返回值的代码作为测试):

const char* Encrypt(LPCTSTR strPValue)
{
String^ strValue = gcnew String(strPValue);
string strReturn = (const char*)(Marshal::StringToHGlobalAnsi(strValue)).ToPointer();

char* csValue = new char[strReturn.size()];
strcpy(csValue, strReturn.c_str());
return const_cast<const char*> (csValue);
}

EXE 函数在“const char* Return = MethodCall(strValue);”上抛出异常(据我所知,我在这个异常上启用了中断)。

为什么这个函数会抛出这个异常?

谢谢!

编辑

更新:我的字符集是 UNICODE。

更新 #2:根据我在建议和答案中读到的内容,您假设这段代码不起作用,但它确实起作用。我启用了对第一次机会异常的中断(是的,我确实知道第一次机会异常是什么),因为我希望这个程序质量好,所有错误都消失了。代码运行良好,我只是想弄清楚为什么会抛出第一次异常,因为我想成为一个更好的程序员。所以我想解决这个问题。

更新 #3:我现在让我的代码检查 hDLL 和 hMethod 的值,并且在运行此函数时两者都不为空。问题似乎出在对 DLL 的调用中。我假设函数签名是 100% 正确的,因为这段代码确实有效,它只是抛出一个第一次机会异常。

更新 #4:我在上面的函数中添加了新的更改,并添加了 DLL 函数代码。 DLL 函数是一个 CLR C++ DLL。我已经删除了 DLL 函数中的所有代码,以确保它不是我的 DLL。

最佳答案

从片段中看不清楚,但看起来您在用 C++/CLI 编写的托管 函数上使用了 __declspec(dllexport)。 String^ 和 Marshal 类使这一点变得明确。

在完全原生的应用程序中运行托管代码是可能的,但它需要加载和初始化 CLR。有几种方法可以做到这一点,我猜你偶然发现了最简单的方法。在托管函数上使用 __declspec(dllexport) 会强制编译器发出一个 stub ,该 stub 负责确保 CLR 已初始化并进行 native 代码到托管代码的转换。

所以是的,当您第一次调用这个导出函数时,一大堆代码会在您的背后执行。那是 stub 需要加载和初始化 CLR 以及加载包含托管代码的程序集的时间。看到这段代码抛出和处理异常通常没什么好担心的。无论如何你对此无能为力,你没有这方面的源代码。您可以通过自己托管 CLR 来减少偶然事件。这需要大量 COM 代码,不确定是否值得付出代价。

根据您提供的明确证据表明这实际上不会导致问题,这是功能,而不是错误。请注意,您可以使用此类代码触发真正的、未处理的异常。如果托管代码抛出托管异常,这在托管代码中很常见,那么您将受到异常代码为 0xe0434f4d 的 Windows SEH 异常的打击。这总是很糟糕,您可以使用 __try 和 __catch 关键字来捕获它,但您无法对其进行适当的诊断,因为在堆栈展开回您的代码时,有关托管异常的所有信息都是奇闻趣事。

关于C++ LoadLibrary 抛出 First-Chance Exception,但有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9987923/

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