我对这一点感到非常难过,请你帮忙。
我试图用一个带有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文件中,这没有任何区别。我真的不确定为什么会发生这种情况所以非常感谢任何帮助。
答案 0 :(得分:6)
您根本没有执行任何错误检查。
很可能LoadLibraryEx
失败并返回NULL
。然后GetProcAddress
失败并返回NULL
。然后,您尝试在地址NULL
处调用函数。或者LoadLibraryEx
成功,但对GetProcAddress
的调用失败,因为您的函数名称错误。函数名称看起来正确,但总是存在名称损坏或装饰的可能性。按照您的出口方式,这意味着这些都不会发生。所以我宁愿怀疑module
是NULL
。
使用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();