Name Decorations, Exported Functions, PInvoke Signatures

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;

image

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.