Omega Doe
Omega Doe

Reputation: 345

force visual studio linker to keep name mangling

i am working on a dll proxy project and i am having problem with forcing the visual studio linker to use the mingling name of the functions.

in my def file i have :

EXPORTS _ap_abort_on_oom@0=__E__0__ @1

but after building the solution the function in the dll is :

_ap_abort_on_oom

when i run the my original prog i get an error that _ap_abort_on_oom@0 not found. i am using the wrappit project how do i change the linker settings so it will use the decorated names?

Upvotes: 1

Views: 626

Answers (3)

Graeme Gill
Graeme Gill

Reputation: 645

This question (and others like it) relate to creating proxy DLLs automatically using the Code Project WRAPPIT tool.

The solution is to always declare the wrapper function to be __stdcall so that it gets decorated with a leading _ and trailing @0, and then use that in the .def file so that the original function decoration (if any) is preserved.

(When/if you replace the wrapper with a real function, you need to remember to change the call convention from __stdcall to the one needed, as well as remove __declspec(naked), add argument declarations etc.)

Wrapper .cpp snipet:

// _OriginalFunction@12
extern "C" __declspec(naked) void __stdcall __E__0__()
    {
    __asm
        {
        jmp p[0*4];
        }
    }

.def file:

EXPORTS
_OriginalFunction@12=___E__0__@0 @1
etc.

I modified my version of the WRAPPIT tool to do this automatically:

165c165
<                       fprintf(fdef,"%s=%s @%u\r\n",v[i].en,v[i].in,v[i].o);
---
>                       fprintf(fdef,"%s=_%s@0 @%u\r\n",v[i].en,v[i].in,v[i].o);
167c167
<                       fprintf(fdef,"%s=%s @%u NONAME\r\n",v[i].en,v[i].in,v[i].o);
---
>                       fprintf(fdef,"%s=_%s@0 @%u NONAME\r\n",v[i].en,v[i].in,v[i].o);
225c225
<               fprintf(fcpp,"// %s\r\nextern \"C\" __declspec(naked) void %s %s()\r\n",v[i].en,argv[3],v[i].in);
---
>               fprintf(fcpp,"// %s\r\nextern \"C\" __declspec(naked) void %s %s()\r\n",v[i].en,"__stdcall",v[i].in);

Upvotes: 2

Andy Brown
Andy Brown

Reputation: 12999

Don't use a .def file, use the __declspec(dllexport) attribute. Here's an example:

test.cpp:

__declspec(dllexport) void foo(int a,int b) {
}

Build:

C:\tmp>cl /c /nologo test.cpp
test.cpp

C:\tmp>link.exe /nologo /dll /out:test.dll test.obj
   Creating library test.lib and object test.exp

Test:

Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file test.dll

File Type: DLL

  Section contains the following exports for test.dll

    00000000 characteristics
    54FD7DE4 time date stamp Mon Mar 09 11:03:00 2015
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 ?foo@@YAXHH@Z

Note that the mangling is present in the foo() function exported in the DLL.

Upvotes: 0

Richard Critten
Richard Critten

Reputation: 2145

It looks like your mangled name has a @ character in it. That is never going to work. The @ character is reserved as the separator between the name and the ordinal.

Source: https://msdn.microsoft.com/en-us/library/hyx1zcd3.aspx

Upvotes: 1

Related Questions