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

我完全被这个难住了,请你帮忙。

我正在试图从一个函数调用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的调用失败,因为你的函数名称错误。 函数名称看起来是正确的,但总是有名称修饰或装饰的可能性。 授予你出口的方式意味着这些都不应该发生。 所以我宁可怀疑moduleNULL

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();