Reputation: 1174
I have worked with "CPPLoadLibrary" example (from Microsoft All-in-One framework) Okay, there are two ways of export symbols from the sample DLL.
And so we have the following code.
typedef int (_cdecl* LPFNGETSTRINGLENGTH1) (PCWSTR);
typedef int (CALLBACK* LPFNGETSTRINGLENGTH2) (PCWSTR);
LPFNGETSTRINGLENGTH1 lpfnGetStringLength1 = (LPFNGETSTRINGLENGTH1)
GetProcAddress(hModule, "GetStringLength1");
LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)
GetProcAddress(hModule, "_GetStringLength2@4");
So my question is how to determine the name of symbol in order to call GetProcAddress? in first case it's pretty straightforward, we take that symbol name from .DEF file. But what about "_GetStringLength2@4" What is underscore? What is "@4" stand for? Thanks.
Upvotes: 0
Views: 1903
Reputation: 400314
If you don't use a .DEF file, the export names are decorated according to their calling convention in order to support exporting overloaded functions. See Why can't I GetProcAddress a function I dllexport'ed?:
[T]he decoration scheme varies from architecture to architecture and from calling convention to calling convention. So, for example, if the function is exported from a PPC DLL, you would have to do
GetProcAddress(hinst, "..SomeFunction")
, but if it is exported from an 80386 DLL asextern "C" __stdcall
, you would needGetProcAddress(hinst, "_SomeFunction@8")
, but if it's__fastcall
you would needGetProcAddress(hinst, "@SomeFunction@8")
.What's more, C++ decoration varies from compiler vendor to compiler vendor. A C++ exported function might require
GetProcAddress(hinst, "?SomeFunction@@YGXHH@Z")
if compiled with the Microsoft C++ compiler, but some other decorated string if compiled with the Borland C++ compiler.So if you intend people to be able to
GetProcAddress
for functions and you intend your code to be portable to multiple platforms, or if you intend them to be able to use your DLL from a language other than C/C++ or use a C++ compiler different from Microsoft Visual Studio, then you must export the function by its undecorated name.
See The history of calling conventions, part3 for a description of the various name decoration schemes. In this case, the function uses the __stdcall
calling convention, so it's decorated by prepending an underscore and appending a @
sign and the number of bytes worth of parameters it takes. It takes one word-sized argument for a total of 4 bytes, so it's decorated as _GetStringLength2@4
.
Upvotes: 3
Reputation: 596537
To answer your actual question, use your compiler's TDUMP or similar tool, or any other tool that can display an executable's exports table, so you can see the actual exported names.
Upvotes: -1