C++ 是否可能在u stdcall中有一个导出的函数,并且名称不混合?
我正在做一个项目,为离线测试生成一个虚拟DLL。我们有真正的DLL及其头文件,尽管它们看起来不兼容。DLL中的名称未混合,但函数前向声明被称为C++ 是否可能在u stdcall中有一个导出的函数,并且名称不混合?,c++,dll,dllexport,stdcall,cdecl,C++,Dll,Dllexport,Stdcall,Cdecl,我正在做一个项目,为离线测试生成一个虚拟DLL。我们有真正的DLL及其头文件,尽管它们看起来不兼容。DLL中的名称未混合,但函数前向声明被称为\uu stdcall: 例h DWORD __stdcall DoSomething(byte aByte); Dependency Walker中的example.dll: 2 (0x0002) 2 (0x0002) DoSomething 0x000831C0 据我所知,如果可以导出\uu stdcall约定中的函数,则其名称在dep
\uu stdcall
:
例h
DWORD __stdcall DoSomething(byte aByte);
Dependency Walker中的example.dll:
2 (0x0002) 2 (0x0002) DoSomething 0x000831C0
据我所知,如果可以导出\uu stdcall
约定中的函数,则其名称在dependency walker中应为:
2 (0x0002) 2 (0x0002) _DoSomething@1 0x000831C0
这是否意味着我们的头文件与已编译的DLL不对应,或者我遗漏了什么
最后,如何形成虚拟函数的导出,使其与我正在模拟的真实DLL的行为相同?只有两种方法可以不获取\u stdcall name装饰:
- 必须使用.def文件重命名导出。通过不使用它来获得成功
- 您将代码构建为目标x64。由于它只有一个调用约定,编译器将忽略您的uu stdcall属性,并且不会修饰名称。现在需要一个.def文件来重命名导出。永远不要这样做,没有人会期望在64位代码中使用装饰
请注意,如果经过修饰,导出的名称将是_DoSomething@4. 名称的@部分表示堆栈激活帧的大小。换句话说,在函数返回之前需要从堆栈中弹出的字节数。对于32位代码,它永远不能是1,它始终是4的倍数。之所以存在此名称修饰,是因为u stdcall非常危险,超出预期的函数弹出堆栈的部分会导致非常难以诊断的堆栈不平衡。链接器捕捉到函数原型声明错误。对于停止更改您之前使用的过程名称,请执行以下操作: 如果使用GNU C++编译器,在“链接器”中添加“<代码> -WL,在< /COD>”中删除参数。 如果使用代码块:
"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
谢谢@Hans,事实证明我们使用的方法在所有方面都可能与您的选项1相同,即使用#pragma重命名export
#pragma注释(linker,“/export:DoSomething=_DoSomething@4)
。感谢对标准字节计数乘法器(32位为4,64位为8)的提示,我看到的所有数字都是4的倍数,这似乎是一种趋势,只是假设了巧合。另外请注意,我一点也不喜欢使用它,我们只是试图复制专有DLL的功能。嗯,我想我必须修改我的答案才能改为三。我将跳过,这不是一个文档化的/EXPORT功能。