This is an open question for me at the time of writing. If I go into Visual Studio 2015 Update 1 and I make a new DLL project as per the dialog here;
and then in the generated MyGreatDll.h file I add a function declaration;
extern "C" void _declspec(dllexport) __stdcall MyFunction();
and then in the generated MyGreatDll.cpp file I add a function definition;
void __stdcall MyFunction() { }
and then I build out 3 DLLs for x86, x64 and ARM using the standard compilation settings and then dump their contents using dumpbin /exports then I see.
For x64
Microsoft (R) COFF/PE Dumper Version 14.00.23506.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file MyGreatDll.dll
File Type: DLL
Section contains the following exports for MyGreatDll.dll
00000000 characteristics
5677EB06 time date stamp Mon Dec 21 12:05:26 2015
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00011172 MyFunction = @ILT+365(MyFunction)
Summary
1000 .00cfg
3000 .data
1000 .gfids
2000 .idata
2000 .pdata
17000 .rdata
1000 .reloc
7000 .text
10000 .textbss
For ARM
Microsoft (R) COFF/PE Dumper Version 14.00.23506.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file MyGreatDll.dll
File Type: DLL
Section contains the following exports for MyGreatDll.dll
00000000 characteristics
5677EB0A time date stamp Mon Dec 21 12:05:30 2015
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001295 MyFunction = @ILT+649(MyFunction)
Summary
1000 .00cfg
1000 .data
1000 .gfids
1000 .idata
1000 .pdata
16000 .rdata
1000 .reloc
8000 .text
For x86
Microsoft (R) COFF/PE Dumper Version 14.00.23506.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file MyGreatDll.dll
File Type: DLL
Section contains the following exports for MyGreatDll.dll
00000000 characteristics
5677EB01 time date stamp Mon Dec 21 12:05:21 2015
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00011208 _MyFunction@0 = @ILT+515(_MyFunction@0)
Summary
1000 .00cfg
1000 .data
1000 .gfids
1000 .idata
16000 .rdata
1000 .reloc
5000 .text
10000 .textbss
What’s the Difference?
The difference is that for the x64 and ARM builds it seems like the name of the exported function is MyFunction without any name decoration whereas for the x86 build it seems like the name of the exported function is _MyFunction@0.
The challenge there is that if you are trying to call this function via a PInvoke then it feels like it makes it slightly tricky because the signature is different across x86, x64 and ARM.
It’s possible to ‘solve’ the problem I think by taking out the _declspec(dllexport) from the header file and, instead, adding a DEF file to the project with something like;
EXPORTS
MyFunction PRIVATE
to it and then that seems to give a consistent function name exported from the DLL in all 3 platform cases.
At the time of writing, I’m not sure whether this is expected behaviour or not and so I’ll update the post if I find out the rationale behind it but, in the meantime, I thought I’d flag it here as something I came across while looking at a customer’s code.