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

1 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;
}
///////////////////////////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)

哪个是从命令行应用程序运行的.(包含在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;
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试将sqrt移动到cpp文件中,这没有任何区别.我真的不确定为什么会这样,所以任何帮助都非常感谢.

Dav*_*nan 6

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

很可能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();
Run Code Online (Sandbox Code Playgroud)