I've build a basic dll and a bit of code to call it. My dll is practically empty, the only things really in it are:
BOOL APIENTRY DllMain( HMODULE hModule,
extern "C" __declspec(dllexport) int doSomething(void)
I can load my Dll into my other code using LoadLibrary and GetProcAddress and everything works fine.
Now if I remove the extern "C" from the definition of doSomething then the library loads fine into my other code but the function can't be found when I call GetProcAddress (using the function name "doSomething"). This is clearly a name mangling problem, i.e. by not including extern "C" the name of doSomething get's mangled as it's viewed as a C++ function.
My question is, when would I write a dll where I didn't use extern "C" to export functions? Presumably if I'm loading a dll using this method (i.e. dynamically) then I'll never want to mangle the name else I'll not know what name to call GetProcAddress with. I can see the same problem with loading the dll using another language as well, e.g. C# (especially since name mangling is compiler determined (I think!)).
Name mangling is necessary to export C++ classes from a dll. The decorations tell the calling routine the parameters and return type so that the compiler can properly determine "this" pointers, overloads, etc.
Okay, so it's for class exporting rather than function exporting. Now I'm not an expert on exporting classes so I'll have to go and play around with this, but a couple of things come to mind:
If I want to export classes with member functions (possibly polymorphic classes) then name mangling is essential right? In which case if I want to import c++ classes into other code then I really do need to know the mangled name? - which sounds pretty inconvenient to me. Furthermore importing will be dependent on which compiler the dll was compiled on as, I believe, that different compilers manged c++ functions in different ways. i.e. if I try and import a dll into my code with a c++ class then the name I use to import than class will be dependent on where the dll was compiled.
Finally, with regards to your last sentence. How can the decorations be used by the compiler when compiling the calling routine? Surely this will all be happening at runtime as I'm dynamically linking?
C++ names mangling allows functions overloading. Without mangling, you cannot export two functions with the same name, but with different set of parameters. Mangling generates unique name based on a function name and parameters type. Writing Dll for C++ clients, and exporting overloaded functions, we use names mangling. Writing Dll for C-style clients, we usually don't need function overloading and define exported functions as extern "C".
Class methods are always mangled, but in any case, class cannot be used by C-style client, and extern "C" cannot be applied to an exported class.
Alex F summed it up nicely. I'd just like to emphasize that only C++ applications can import C++ classes from a dll and only with a bunch of caveats. For OO class usage by other languages, MS developed OLE/COM.
My question is, when would I write a dll where I didn't use extern "C" to export functions?
Well, you know, explicit dynamic linking actually is very rare beast in contemporary programming world. Implicit linking is used most of the times. As long as those mangled names are embedded into import library, this your "huge" problem appears minuscule in real, as now import library takes care about the name thing. Summarizing, most of the times people never care about unmangling C++ names, unless they knowingly avoid mangling because of imposed particular limitations, or some whim maybe.
There is really only one single 'right' answer for this...
You will/must use name mangling when you are compiling the DLL and ALL the applications using this DLL using the very same brand and version of the compiler and you are statically binding to the DLL via the importlib.
For everything else... either extern "C" is more appropriate or there isn't a suitable solution at all.
Last edited by OReubens; February 3rd, 2010 at 09:34 AM.