I have the following code in a .dll:
namespace MyNamespace
{
extern "C" __declspec(dllexport) int __stdcall GetOptionID(unsigned long num)
{
return 0;
}
}
This is compiled on Visual C++ 2010, so I also have a .def file containing GetOptionID
. I can see that the function is exported, and mangled as _GetOptionID@4
, using dumpbin /exports:
File Type: DLL
Section contains the following exports for MyLibrary.dll
00000000 characteristics
53D269CB time date stamp Fri Jul 25 15:29:31 2014
0.00 version
1 ordinal base
13 number of functions
13 number of names
ordinal hint RVA name
1 0 0006F030 CmdOne = _CmdOne@16
2 1 0006F510 CmdUnimpl = _CmdUnimpl@16
3 2 0006EBB0 DefineThing = _DefineThing@32
4 3 0006E0C0 GetOptionID = _GetOptionID@4
In a separate executable, I attempt to check for the presence of GetOptionID
:
HINSTANCE hinst = LoadLibraryEx(file_name, NULL, DONT_RESOLVE_DLL_REFERENCES);
if(!hinst)
return FALSE;
FARPROC_IDI lp = (FARPROC_IDI) GetProcAddress(hinst, "_GetOptionID@4");
auto e = GetLastError();
Running through this code in the debugger, I can see that:
LoadLibraryEx
succeeds - I have a valid-looking hinst
GetProcAddress
fails - lp
is 0x00000000
GetLastError
returns 127I can see the function has been exported, and I can see its name matches the entry point I'm looking for. How come GetProcAddress
is failing?
Ah, solved it myself. Defining the function in the .def file causes its name to be completely unmangled, meaning the correct target for GetProcAddress
was simply GetOptionID
.
However, since I have other .dlls that undergo the same check and really are _GetOptionID@4
, the actual solution was to remove GetOptionID from the .def file.