2014-06-25 49 views
3

我正在为一个项目生成一个用于离线测试的虚拟DLL。我们有真正的DLL和它的头文件,虽然它们看起来不兼容。在DLL的名称是未重整但功能的前置声明声明被召唤出来为__stdcall是否有可能在__stdcall中有一个导出的函数,并且名称是否已解除?

example.h文件

DWORD __stdcall DoSomething(byte aByte); 

example.dll中的Dependency Walker:

2 (0x0002) 2 (0x0002) DoSomething 0x000831C0 

至于我读过,如果有可能在__stdcall公约中输出一个函数,它的名字应该在依赖关系者中读作:

2 (0x0002) 2 (0x0002) [email protected] 0x000831C0 

这是否意味着我们的头文件与编译的DLL不对应,还是我错过了某些东西?

最终,我如何形成虚拟函数的导出,以便像我正在模拟的实际DLL那样执行相同的操作?

回答

4

只有两种方法来得到__stdcall名称修饰:

  • 必须使用DEF文件重命名的出口。先不使用它。

  • 您已将您的代码构建到目标x64。由于它只有一个调用约定,编译器会忽略你的__stdcall属性,它不会修饰名称。现在你需要需要一个.def文件来重命名导出。永远不要这样做,没有人会期望在64位代码中使用装饰。

请注意,如果装饰,导出的名称将是_DoSomething @ 4。名称的@部分表示堆栈激活帧的大小。换句话说,函数返回之前需要从堆栈中弹出的字节数。对于32位代码,它永远不会是1,它总是4的倍数。这个名称的存在是因为__stdcall非常危险,函数弹出比预期更多或更少的堆栈会导致非常难以诊断堆栈不平衡。链接器捕获函数原型声明错误。

+0

感谢@Hans,事实证明,我们使用,可能在各方面都等于你选择1的方法,即是通过使用#pragma来重命名导出'#pragma comment(linker,“/ export:DoSomething = _DoSomething @ 4”)''。感谢标准字节计数乘法器的提示(32位的4位,64位的8位),它看起来像是一种趋势,我所看到的所有数字都是4的倍数,只是巧合。 –

+0

还要注意,它并不是我的首选,我们只是试图复制专有DLL的功能。 –

+0

嗯,我想我不得不编辑我的答案改为*三*。我会跳过,这不是记录的/ EXPORT功能。 –

0

停止更改过程名称,您使用__stdcall之前: 如果您使用gnu C++编译器将“-Wl,--kill-at”参数添加到您的链接器。

,如果你使用的代码块:

"Settings" -> "Compiler..." 
"Global compiler settings" 
"Linker settings" 
"Other linker options": 
add: "-Wl,--kill-at" 

如果使用DEVC++

project->project options 
Parameters 
add "-Wl,--kill-at" to linker 
相关问题