32

I'm trying to create a DLL that exports a function called "GetName". I'd like other code to be able to call this function without having to know the mangled function name.

My header file looks like this:

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

EXPORT TCHAR * CALLBACK GetName();

My code looks like this:

#include <windows.h>
#include "PluginOne.h"

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
     return TRUE ;
}

EXPORT TCHAR * CALLBACK GetName()
{
    return TEXT("Test Name");
}

When I build, the DLL still exports the function with the name: "_GetName@0".

What am I doing wrong?

Slapout
  • 3,759
  • 5
  • 40
  • 61

4 Answers4

30

Small correction - for success resolving name by clinet

extern "C"

must be as on export side as on import.

extern "C" will reduce name of proc to: "_GetName".

More over you can force any name with help of section EXPORTS in .def file

Dewfy
  • 23,277
  • 13
  • 73
  • 121
  • Hey cool this is exactly almost what I need. Now what if I want it the other way around? I have C function, completely fine to be c++ member function (vtable, calling convention all done), but the compiler figures it's name should be mangled. – Pyjong Jan 26 '15 at 12:57
  • Yes, C and C++ use different name decoration rules. To do what you asking about you need create wrapper that will invoke C function from C++ class member – Dewfy Jan 27 '15 at 09:33
  • 1
    A .DEF file is the only way to disable name mangling. `extern "C"` will still use name decoration, just not as verbose as C++ needs to. – IInspectable Apr 20 '17 at 18:37
10

This is normal for a DLL export with a __stdcall convention. The @N indicates the number of bytes that the function takes in its arguments -- in your case, zero.

Note that the MSDN page on Exporting from a DLL specifically says to "use the __stdcall calling convention" when using "the keyword __declspec(dllexport) in the function's definition".

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • 3
    As mentioned [here](http://stackoverflow.com/questions/2804893/c-dll-export-decorated-mangled-names), the only way to overcome the mangling of a `__stdcall` is to use: `#pragma comment(linker, "/EXPORT:SomeFunction=_SomeFunction@@@23mangledstuff#@@@@")` – Pierre Jun 17 '13 at 04:16
  • 2
    your first link is broken and the second points to a download – Simon Mourier Dec 19 '17 at 10:35
7

the right answer is the following:

extern "C" int MyFunc(int param);

and

int MyFunc(int param);

is two declarations which uses different internal naming, first - is in C-style, second - in the C++ style.

internal naming required for build tools to determine which arguments function receives, what type returns etc, since C++ is more complicated (oop's, overloaded, virtual functions etc) - it uses more complicated naming. calling convention also affects both c and c++ namings.

both this styles of naming is applied when using __declspec(dllexport) in the same manner.

if you want to omit name mangling of exported routine, add a module definition file to your project, type in it (in this case you not required to declspec dllexport):

LIBRARY mylib
EXPORTS
  MyFunc

this will omit explicit name decoration (samples below).

_MyFunc (c style, __cdecl)
_MyFunc@4 (c style, __stdcall)
?MyFunc@@YAHH@Z (c++ style, __cdecl)
?MyFunc@@YGHH@Z (c++ style, __stdcall)
sn0w
  • 71
  • 1
  • 1
4

You can use the "-Wl,--kill-at" linker switch to disable name mangling.

For example, in Code::Blocks, in the custom linker settings, add: -Wl,--kill-at

vga None
  • 73
  • 2
  • 6