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();
}
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
extern "C"
to specify it.__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.