GetProcAddress does not find function in DLL

469 Views Asked by At

I have a DLL and I want to call a function in it. I check the DLL using Dependency Walker and the result I got is:

 void U2U_Test(void)

This is the code that I wrote, but GetProcAddress() returns NULL:

typedef void(*U2U_Test_pointer)();

void  check() {

    HINSTANCE hGetProcIDDLL1 = LoadLibrary(_T("my_dll.dll"));

    if (hGetProcIDDLL1 == NULL)
        return;

    U2U_Test_pointer addr = (U2U_Test_pointer)GetProcAddress(hGetProcIDDLL1, "U2U_Test");

    if (addr == NULL)
        return;

    return addr();
}
1

There are 1 best solutions below

0
On

Depending on conventions and compiler used, the actual name exported in the DLL might not be exactly the same as the one you wrote in your source code. This phenomenon is commonly called name decoration or name mangling.

In fact you are guaranteed to have exactly the same name only if

  • Your compiler conforms to C conventions (probably it does)
  • The function is exported in C and not C++. Use extern "C" to specify it.
  • The calling convention is _cdecl (specify __cdecl in function declaration)

For example, when call convention is __stdcall instead of __cdecl, which is common for many windows DLLs (they often write WINAPI or CALLBACK instead of __sstdcall), the name of the exported function is often suffixed by @n where n is the number of bytes expected on the stack for parameters. In your case, it could be U2U_Test@0. Indications like __declspec(dllimport) and __declspec(dllexport) tell the compiler to automatically take care of that kind of thing when DLLs are imported/linked at compile time.

IN C++, complex name decoration is used in order to support methods, function overloading, templates and other features, and each compiler invented crazy naming schemes to make sure there won't ever be any clash. Because at DLL level, there's no template, no classes, only a list of exported symbols indexed by their name or an ID. That's the reason why most DLLs are exported in C and why most header files declare functions coming from DLL inside a extern "C" { ... } block.