我正在开发一个dll代理项目,我遇到了强迫visual studio链接器使用函数混合名称的问题。
在我的def文件中我有:
EXPORTS
_ap_abort_on_oom@0=__E__0__ @1
但是在构建解决方案之后,dll中的函数是:
_ap_abort_on_oom
当我运行我的原始编程时,我收到错误,找不到_ap_abort_on_oom @ 0。我正在使用wrappit项目 如何更改链接器设置以便使用装饰名称?
答案 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)
看起来您的受损名称中包含@
字符。这永远不会奏效。 @
字符保留为名称和序号之间的分隔符。
答案 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()
函数中。