1
votes

I am thoroughly stumped on this one, can you please help.

I am trying to call the sqrt from a function with a Dll. When doing so I get the following error,

First-chance exception at 0x000082bc in DllTest.exe: 0xC0000005: Access violation.

The exception happens when the sqrt is called.

The code in my Dll is (contained in the header)

/////////////////////////////////////////////////////////////
#include <math.h> 

//////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) float MyFunction (void)
{
float f(10.0f);

float r(sqrt(f));

return r;
}
///////////////////////////////////////////////////////////

Which is run from a command line application. (Contained in the cpp file)

#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;
}

I have tried moving the sqrt into the cpp file which made no difference. I am really not sure why this could be happening so any help is greatly appreciated.

1

1 Answers

6
votes

You are not performing any error checking at all.

Quite possibly LoadLibraryEx fails and returns NULL. Then GetProcAddress fails and returns NULL. You then try to call a function at address NULL. Or perhaps LoadLibraryEx succeeds, but the call to GetProcAddress fails because you got the function name wrong. The function name looks right, but there is always the possibility of name mangling or decoration. Granted the way you have exported it means neither of those should happen. So I rather suspect that module is NULL.

The use of DONT_RESOLVE_DLL_REFERENCES puzzles me. I cannot imagine why you included that. The documentation says:

If this value is used, and the executable module is a DLL, the system does not call DllMain for process and thread initialization and termination. Also, the system does not load additional executable modules that are referenced by the specified module.

Note Do not use this value; it is provided only for backward compatibility. If you are planning to access only data or resources in the DLL, use LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or LOAD_LIBRARY_AS_IMAGE_RESOURCE or both. Otherwise, load the library as a DLL or executable module using the LoadLibrary function.

That is as clear as can be. Do not use this value. In fact, you should just call LoadLibrary. You do not need the added functionality that LoadLibraryEx offers.

The fact that the error is raised in the DllTest.exe module indicates that you never make it into the DLL. And so I'm reasonably confident that one of my hypotheses above is accurate.

Add some error checking. The documentation for the functions that you call tell you how to do that. Specifically you will need to check the return values of the functions that you call. For both of these functions a return value of NULL indicates failure. And, for both of these functions, when they fail you can obtain an error code by calling GetLastError. But not all Win32 functions work that way so always read the documentation carefully and always check for errors.

You want code that looks like this:

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