我完全被这个难住了,请你帮忙。
我正在试图从一个函数调用sqrt与一个DLL。 当这样做,我得到以下错误,
DllTest.exe中0x000082bc第一次机会exception:0xC0000005:访问冲突。
sqrt被调用时发生exception。
我的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或两者。 否则,使用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();