23

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");
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Alireza
  • 1,018
  • 1
  • 8
  • 23
  • 2
    Is that function exported from the DLL? – sharptooth May 17 '11 at 13:25
  • yes, I wrote that DLL and make .def file and compile it with lib.exe – Alireza May 17 '11 at 13:28
  • Did you use C++ decoration for `GetNumber` in DLL? It's the most probably reason. You need to use `extern "C"` notation – DReJ May 17 '11 at 13:33
  • Did you try calling GetLastError() after GetProcAddress failed? What was the return value? – Boaz Yaniv May 17 '11 at 13:36
  • @DReJ: IIRC, if he explicitly specified the function in a .def file, there's no need for extern "C". – Boaz Yaniv May 17 '11 at 13:38
  • 5
    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. – Fozi May 17 '11 at 13:43
  • @Boaz: Yep, you're right. So it must be mistake in .def. – DReJ May 17 '11 at 13:46
  • There's also a GUI tool called depends.exe (or Dependency Walker) which can show you all the functions exported by your DLL. – Boaz Yaniv May 17 '11 at 13:54
  • 1
    @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(). – Lucky Luke May 17 '11 at 14:09
  • 1
    @Lucky Luke: To rephrase what you said: On non-stone-age systems [HINSTANCE and HMODULE are one and the same](http://blogs.msdn.com/b/oldnewthing/archive/2004/06/14/155107.aspx). – Boaz Yaniv May 17 '11 at 14:44

3 Answers3

53

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();
};
John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • Tip #2 worked for me like a charm! I figured you needed the `extern "C"` or `__declspec(dllexport)` but turns out you need both... – Chef Pharaoh May 24 '14 at 16:48
  • 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? – Chef Pharaoh May 24 '14 at 17:14
  • @ChefPharaoh: You can access a class member just as well. You have to provide the [decorated name](https://msdn.microsoft.com/en-us/library/2ax8kbk1.aspx) to the call to `GetProcAddress`, though. Using decorated names has not been explained in this answer, unfortunately. – IInspectable Feb 05 '16 at 14:38
  • Thanks very nice. i had this problem too. – BattleTested_закалённый в бою Jul 29 '18 at 06:30
  • 1
    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? – BattleTested_закалённый в бою Jul 29 '18 at 07:07
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

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.

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • NO I checked the loadlibrary and it doesn't return NULL. just the getprocaddress returns NULL – Alireza May 17 '11 at 13:30
  • I'm assuming you know how to create and export a symbol in a DLL. If you don't, check this tutorial: http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855 or this one: http://www.programmers-corner.com/tutorial/4 – karlphillip May 17 '11 at 13:31
  • Well, your source code is deceiving. In the future you might want to fix that since it will come to your advantage. – karlphillip May 17 '11 at 13:33