迫使视觉工作室链接器保持名称错误

时间:2015-03-09 09:25:25

标签: c++ visual-studio visual-studio-2012 dll linker

我正在开发一个dll代理项目,我遇到了强迫visual studio链接器使用函数混合名称的问题。

在我的def文件中我有:

EXPORTS _ap_abort_on_oom@0=__E__0__ @1

但是在构建解决方案之后,dll中的函数是:

_ap_abort_on_oom

当我运行我的原始编程时,我收到错误,找不到_ap_abort_on_oom @ 0。我正在使用wrappit项目 如何更改链接器设置以便使用装饰名称?

3 个答案:

答案 0 :(得分:2)

这个问题(和其他类似的问题)涉及使用Code Project WRAPPIT工具自动创建代理DLL。

解决方案是始终将包装函数声明为__stdcall,以便它使用前导_和尾随@ 0进行修饰,然后在.def文件中使用它,以便保留原始函数修饰(如果有)

(当/如果用真实函数替换包装器时,需要记住将调用约定从__stdcall更改为所需的调用约定,以及删除__declspec(裸),添加参数声明等。)

Wrapper .cpp snipet:

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

.def文件:

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

我修改了我的WRAPPIT工具版本来自动执行此操作:

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);

答案 1 :(得分:1)

看起来您的受损名称中包含@字符。这永远不会奏效。 @字符保留为名称和序号之间的分隔符。

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

答案 2 :(得分:0)

请勿使用.def文件,请使用__declspec(dllexport)属性。这是一个例子:

<强> TEST.CPP:

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

<强>构建

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

<强>测试

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

请注意,修改存在于DLL中导出的foo()函数中。