GetProcAddress function in C++
Asked Answered
S

3

24

Hello guys: I've loaded my DLL in my project but whenever I use the GetProcAddress function. it returns NULL! what should I do? I use this function ( double GetNumber(double x) ) in "MYDLL.dll"

Here is a code which I used:

typedef double (*LPGETNUMBER)(double Nbr);
HINSTANCE hDLL = NULL;
LPGETNUMBER lpGetNumber;
hDLL = LoadLibrary(L"MYDLL.DLL");
lpGetNumber = (LPGETNUMBER)GetProcAddress((HMODULE)hDLL, "GetNumber");
Sponge answered 17/5, 2011 at 13:24 Comment(10)
Is that function exported from the DLL?Flaxseed
yes, I wrote that DLL and make .def file and compile it with lib.exeSponge
Did you use C++ decoration for GetNumber in DLL? It's the most probably reason. You need to use extern "C" notationHasbeen
Did you try calling GetLastError() after GetProcAddress failed? What was the return value?Harbot
@DReJ: IIRC, if he explicitly specified the function in a .def file, there's no need for extern "C".Harbot
Try dumpbin /exports mydll.dll in a command prompt to see what the names of the exports are in your dll. You get dumpbin with your VS, or for free from MS as part of the platform SDK.Mcclimans
@Boaz: Yep, you're right. So it must be mistake in .def.Hasbeen
There's also a GUI tool called depends.exe (or Dependency Walker) which can show you all the functions exported by your DLL.Harbot
@Alireza: If GetProcAddress() returns null, then it means that Windows can't locate that entry point in the DLL. There is also no reason to cast the hDLL variable, LoadLibrary() returns a HMODULE which is the first input parameter to GetProcAddress().Esquivel
@Lucky Luke: To rephrase what you said: On non-stone-age systems HINSTANCE and HMODULE are one and the same.Harbot
Z
55

Checking return codes and calling GetLastError() will set you free. You should be checking return codes twice here. You are actually checking return codes zero times.

hDLL = LoadLibrary(L"MYDLL.DLL");

Check hDLL. Is it NULL? If so, call GetLastError() to find out why. It may be as simple as "File Not Found".

lpGetNumber = (LPGETNUMBER)GetProcAddress((HMODULE)hDLL, "GetNumber");

If lpGetNumber is NULL, call GetLastError(). It will tell you why the proc address could not be found. There are a few likely scenarios:

  1. There is no exported function named GetNumber
  2. There is an exported function named GetNumber, but it is not marked extern "c", resulting in name mangling.
  3. hDLL isn't a valid library handle.

If it turns out to be #1 above, you need to export the functions by decorating the declaration with __declspec(dllexport) like this:

MyFile.h

__declspec(dllexport) int GetNumber();

If it turns out to be #2 above, you need to do this:

extern "C"
{
  __declspec(dllexport) int GetNumber();
};
Zingaro answered 17/5, 2011 at 13:34 Comment(5)
Tip #2 worked for me like a charm! I figured you needed the extern "C" or __declspec(dllexport) but turns out you need both...Frydman
Now why can't I get the address of a class function? 1) Does it need to be a static member? 2) Can it be within a namespace?Frydman
@ChefPharaoh: You can access a class member just as well. You have to provide the decorated name to the call to GetProcAddress, though. Using decorated names has not been explained in this answer, unfortunately.Houdini
Thanks very nice. i had this problem too.Corroboration
is my explanation right? c++ compiler may change int GetNumber(); name (as name mangling technique). so if this happened, declaration and definition would be mismatch(especially when using of external libraries). So we add extern "C" to that compiler behaves this portion as c language (and in c language there's no mangling and function overloading). by the way extern "c" usually used in libraries, right?Corroboration
K
4

You might want to check if your GetNumber function is exported as an __stdcall function.

If so, try GetProcAddress(hDLL, "_GetNumber@N");, where N is the total number of bytes of GetNumber's argument list. For example, if your function signature is int GetNumber(int a, double b), its real name in DLL will be _GetNumber@12.

Reference: __stdcall

Karalynn answered 4/11, 2015 at 4:57 Comment(0)
J
3

Most probably LoadLibrary() failed. You just can't see that because apparently you are not checking what it is returning:

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

EDIT:

We don't know how you are exporting the function on the DLL code, but this thread explains a couple of reasons on why GetProcAddress fails.

Jameljamerson answered 17/5, 2011 at 13:27 Comment(3)
NO I checked the loadlibrary and it doesn't return NULL. just the getprocaddress returns NULLSponge
I'm assuming you know how to create and export a symbol in a DLL. If you don't, check this tutorial: codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855 or this one: programmers-corner.com/tutorial/4Jameljamerson
Well, your source code is deceiving. In the future you might want to fix that since it will come to your advantage.Jameljamerson

© 2022 - 2024 — McMap. All rights reserved.