在C ++中从dll调用sqrt。访问冲突

时间:2013-12-04 18:15:40

标签: c++ windows dll

我对这一点感到非常难过,请你帮忙。

我试图用一个带有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文件中,这没有任何区别。我真的不确定为什么会发生这种情况所以非常感谢任何帮助。

1 个答案:

答案 0 :(得分:6)

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

很可能LoadLibraryEx失败并返回NULL。然后GetProcAddress失败并返回NULL。然后,您尝试在地址NULL处调用函数。或者LoadLibraryEx成功,但对GetProcAddress的调用失败,因为您的函数名称错误。函数名称看起来正确,但总是存在名称损坏或装饰的可能性。按照您的出口方式,这意味着这些都不会发生。所以我宁愿怀疑moduleNULL

使用DONT_RESOLVE_DLL_REFERENCES让我感到困惑。我无法想象为什么你把它包括在内。 documentation说:

  

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

     

注意不要使用此值;它仅用于向后兼容。如果您计划仅访问数据或资源   DLL,使用LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE或   LOAD_LIBRARY_AS_IMAGE_RESOURCE或两者。否则,将库加载为   使用LoadLibrary函数的DLL或可执行模块。

尽可能清楚。 请勿使用此值。实际上,您只需拨打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();