C++ DLL Export: Decorated/Mangled names

56,297

Solution 1

You can get what you want by turning off debug info generation. Project + Properties, Linker, Debugging, Generate Debug Info = No.

Naturally, you only want to do this for the Release build. Where the option is already set that way.

Solution 2

Instead of using .def file just insert pragma comment like this

#pragma comment(linker, "/EXPORT:SomeFunction=_SomeFunction@@@23mangledstuff#@@@@")

Edit: Or even easier: Inside the body of the function use

#pragma comment(linker, "/EXPORT:"__FUNCTION__"="__FUNCDNAME__)

. . . if you have troubles finding the decorated function name. This last pragma can be further reduced with a simple macro definition.

Solution 3

You have to declare the functions as extern "C" if you don't want their names to be mangled.

Solution 4

From experience, be careful if you use __stdcall in your function signature. With __stdcall, the name will remain mangled to some extent (you will find out quickly enough). Apparently, there are two levels of mangling, one the extern "C" deals with at the C++ level, but it does not deal with another level of name mangling caused by __stdcall. The extra mangling is apparently relevant to overloading -- but I am not certain of that.

Solution 5

Even without the mangling, the 32-bit and 64-bit builds name exports differently, even with extern "C". Check it out with DEPENDS.EXE.

This can mean BIG trouble to any client that does a LoadLibrary+GetProcAdress to access your function.

So, on top of all the others use a Module Definition File as follows:

LIBRARY MYDLL
EXPORTS
myFunction=myFunction

Yeap, it's a bit of a pain to maintain, but then how many exported functions do you write a day?

Moreover, I usually change the macros like shown below, since my DLLs export functions not C++ classes and I want them to be callable by most programming environments:

#ifdef WTS_EXPORTS
#define WTS_API(ReturnType) extern "C" __declspec(dllexport) ReturnType WINAPI
#else
#define WTS_API(ReturnType) extern "C" __declspec(dllimport) ReturnType WINAPI
#endif

WTS_API(int) fnWTS(void);

The last line used to confuse VisualAssistX a couple of years ago, I don't know if it properly digests it now :-)

Share:
56,297
Bob
Author by

Bob

Updated on March 14, 2020

Comments

  • Bob
    Bob over 4 years

    Created basic C++ DLL and exported names using Module Definition file (MyDLL.def). After compilation I check the exported function names using dumpbin.exe I expect to see:

    SomeFunction
    

    but I see this instead:

    SomeFunction = SomeFunction@@@23mangledstuff#@@@@
    

    Why?

    The exported function appears undecorated (especially compared to not using the Module Def file), but what's up with the other stuff?

    If I use dumpbin.exe against a DLL from any commercial application, you get the clean:

    SomeFunction
    

    and nothing else...

    I also tried removing the Module Definition and exporting the names using the "C" style of export, namely:

    extern "C" void __declspec(dllexport) SomeFunction();
    

    (Simply using "extern "C" did not create an exported function)

    However, this still creates the same output, namely:

    SomeFunction = SomeFunction@@@23mangledstuff#@@@@
    

    I also tried the #define dllexport __declspec(dllexport) option and created a LIB with no problem. However, I don't want to have to provide a LIB file to people using the DLL in their C# application.

    It's a plain vanilla C++ DLL (unmanaged code), compiled with C++ nothing but a simple header and code. Without Module Def I get mangled exported functions (I can create a static library and use the LIB no problem. I'm trying to avoid that). If I use extern "C" __declspec(dllexport) OR a Module Definition I get what appears to be an undecorated function name... the only problem is that it is followed by an "=" and what looks like a decorated version of the function. I want to get rid of the stuff after the "=" - or at least understand why it is there.

    As it stands, I'm pretty certain that I can call the function from C# using a P/Invoke... I just want to avoid that junk at the end of the "=".

    I'm open to suggestions on how to change the project/compiler settings, but I just used the standard Visual Studio DLL template - nothing special.