在C++中从dll调用sqrt.访问违规

Calling sqrt from dll in C++. Access violation

本文关键字:访问 sqrt 调用 C++ 中从 dll      更新时间:2023-10-16

我被这个问题彻底难住了,你能帮忙吗。

我正试图从一个带有Dll的函数中调用sqrt。当这样做时,我得到以下错误,

DllTest.exe中0x000082bc处的首次机会异常:0xC0000005:访问冲突。

调用sqrt时会发生异常。

我的Dll中的代码是(包含在标题中)

/////////////////////////////////////////////////////////////
#include <math.h> 
//////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) float MyFunction (void)
{
float f(10.0f);
float r(sqrt(f));
return r;
}
///////////////////////////////////////////////////////////

它是从命令行应用程序运行的。(包含在cpp文件中)

#include "stdafx.h"
///////////////////////////////////////////////////////
typedef float (*MyDllFn)(void);
//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE module  = LoadLibraryEx(_T("MyDll.dll"), 
                                NULL,
                                DONT_RESOLVE_DLL_REFERENCES);
MyDllFn         pMyDllFunction ((MyDllFn)       GetProcAddress(module,  "MyFunction"));

float sqrt10 = pMyDllFunction();
return 0;
}

我已经尝试将sqrt移到cpp文件中,但没有任何区别。我真的不知道为什么会发生这种情况,所以我们非常感谢任何帮助。

您根本没有执行任何错误检查。

很可能LoadLibraryEx失败并返回NULL。则GetProcAddress失败并返回NULL。然后尝试调用地址为NULL的函数。或者LoadLibraryEx成功了,但对GetProcAddress的调用失败了,因为您弄错了函数名。函数名称看起来是正确的,但总是存在名称篡改或修饰的可能性。当然,按照你的出口方式,这意味着这两种情况都不应该发生。所以我怀疑module就是NULL

DONT_RESOLVE_DLL_REFERENCES的使用让我很困惑。我无法想象你为什么把它包括在内。文件上写着:

如果使用此值,并且可执行模块是DLL,则系统不为进程和线程初始化调用DllMain,并且结束此外,系统不会加载其他可执行文件指定模块引用的模块。

注意请勿使用此值;它只是为了向后兼容性而提供的。如果您计划只访问中的数据或资源DLL,请使用LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE或LOAD_LIBRARY_AS_IMAGE_RESOURCE或两者兼有。否则,将库加载为DLL或使用LoadLibrary函数的可执行模块。

这是非常清楚的。不要使用此值事实上,您应该只调用LoadLibrary。您不需要LoadLibraryEx提供的附加功能。

在DllTest.exe模块中引发错误的事实表明您从未将其放入DLL中。所以我有理由相信我上面的一个假设是准确的。

添加一些错误检查。您调用的函数的文档会告诉您如何做到这一点。具体来说,您需要检查所调用函数的返回值。对于这两个函数,返回值NULL表示失败。而且,对于这两个函数,当它们失败时,您可以通过调用GetLastError来获得错误代码。但并不是所有的Win32函数都是这样工作的,所以总是仔细阅读文档,始终检查错误。

你想要这样的代码:

HMODULE module  = LoadLibrary(L"MyDll.dll");
if (module == NULL)
    return GetLastError(); // or do some real error handling
MyDllFn pMyDllFunction = (MyDllFn)GetProcAddress(module, "MyFunction");
if (pMyDllFunction == NULL)
    return GetLastError(); // or do some real error handling
float sqrt10 = pMyDllFunction();