Sign in to follow this  
SteveDeFacto

Get signature from C++ function name?

Recommended Posts

I exported a function from my DLL called "add" which just adds two ints together and returns the sum. I exported it as a C++ function in order to get the signature from the name, I know it can be done but I don't know how to do it. "?add@@YAHHH@Z" is the name of the function after it is exported from the DLL, now how do I get data which represents the signature from that?

Share this post


Link to post
Share on other sites
Note that while this will work as long as your functions export only simple types (int, float, etc), it won't be much good if they export more "complex" types. For example, if the method takes a class or struct, you'll be able to find out the name of the struct, but that won't tell you anything about the members of that struct.

That may or may not be important, of course...

Share this post


Link to post
Share on other sites
You're pretty much out of luck here. The name mangling algorithm is undocumented, and while there's been some work into reverse engineering it, it's not complete.

If symbol files for the DLL are present, you can use the DBGHELP api and/or the DIA SDK. Be warned however, this is no easy task. There are lots of little corner cases to handle if you want to be able to parse arbitrarily complex function signatures.

Share this post


Link to post
Share on other sites
Hmm, I admit I didn't know about this function. My response came from the fact that I once implemented my own undecoration based on DIA SDK because I actually needed semantic info about the types of various arguments, as opposed to just a flat textual representation of the entire signature. I guess if the OP doesn't need that though, perhaps this function suffices.

Share this post


Link to post
Share on other sites
Arent you guys overcomplicating this? All i do when i want to unmangle exported function name from a dll project is to add a simple .def file to it, wich look like this:

EXPORTS
SomeFunction @1
SomeOtherFunction @2
... ect

in your case, it should look that way:

.def file

EXPORTS
Add @1



.h file

#define EXP_FUNC __stdcall

void EXP_FUNC Add(int x1, int x2);



.cpp

void EXP_FUNC Add(int x1, int x2)
{

}

Share this post


Link to post
Share on other sites
[quote]Original post by Vortez
Arent you guys overcomplicating this? All i do when i want to unmangle exported function name from a dll project is to add a simple .def file to it, wich look like this:/quote]

His original problem statement implies that he wants to take an EXISTING dll file, for which he does not necessarily have source code and cannot recompile, and DETERMINE at runtime the signature of every function exported by that dll. He doesn't want to actually produce DLL files whose exported function names are unmangled, because as you mention, that is easy.

Share this post


Link to post
Share on other sites
Quote:
Original post by Vortez
Ah, i though it was is own dll.


Well actually when I read it again, you're right it does say it's his own DLL. But still, the problem with C++ is that you can export classes and member functions. And for this to work, it has to mangle the name, If he's only exporting global functions and no class types, then maybe your solution is appropriate

Share this post


Link to post
Share on other sites
Quote:
His original problem statement implies that he wants to take an EXISTING dll file, for which he does not necessarily have source code and cannot recompile, and DETERMINE at runtime the signature of every function exported by that dll. He doesn't want to actually produce DLL files whose exported function names are unmangled, because as you mention, that is easy.


Not necessarily, it is my own DLL but the reason I want to demangle the names is not only to get the name but also the structure of the function, if there is another way to get the structure of a function from the DLL please tell me because I would love to be able to support functions that are exported as C functions.

Share this post


Link to post
Share on other sites
Once a DLL is compiled, all type information is lost. You can infer some of that information from the mangled name, but not all of it (only basic types such as int, float, as I mentioned above). Name mangling in C++ is not really meant to solve this problem anyway, it's just required so that method overloads will generate unique exported names from the DLL.

It's also totally non-standard. Here's a table showing how different compilers will mangle a function. I guess it's OK if you're going to assume everything is compiled with VC++, but obviously it's not portable (for example, the mingw compiler uses the GCC mangling form).

If you really want to be able to do runtime reflection, you need something like COM or .NET.

Share this post


Link to post
Share on other sites
If you do the dll yourself and want an easy way to export functionality I usually make on function that exports a class interface.
The code that uses the DLL would need the interface header tho so that might not be what you want :)

Having a common interface also allows you do load different versions of the dll (OpenGL/D3D render for instance) which is handy for a dll based plugin system

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Once a DLL is compiled, all type information is lost. You can infer some of that information from the mangled name, but not all of it (only basic types such as int, float, as I mentioned above). Name mangling in C++ is not really meant to solve this problem anyway, it's just required so that method overloads will generate unique exported names from the DLL.

It's also totally non-standard. Here's a table showing how different compilers will mangle a function. I guess it's OK if you're going to assume everything is compiled with VC++, but obviously it's not portable (for example, the mingw compiler uses the GCC mangling form).

If you really want to be able to do runtime reflection, you need something like COM or .NET.


Hmmm I didn't think about that, I have it working but now that you brought that up I think I'll need to find another way to do this... Probably going to use something like a header in script, not sure about the details yet though but I'll figure something out...

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Once a DLL is compiled, all type information is lost. You can infer some of that information from the mangled name, but not all of it (only basic types such as int, float, as I mentioned above). Name mangling in C++ is not really meant to solve this problem anyway, it's just required so that method overloads will generate unique exported names from the DLL.

It's also totally non-standard. Here's a table showing how different compilers will mangle a function. I guess it's OK if you're going to assume everything is compiled with VC++, but obviously it's not portable (for example, the mingw compiler uses the GCC mangling form).

If you really want to be able to do runtime reflection, you need something like COM or .NET.


Well, as I mentioned earlier if you have a PDB you can do it with the DIA SDK. That's what a debugger (like VS) does. But it's highly nontrivial, and I'm guessing he doesn't want to require there be a PDB around in order for his code to work.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this