我想通过
std::unique_ptr
管理一个WinAPI函数对:
#include <memory>
int* __stdcall construct(){ return new int{5}; }
void __stdcall destruct(int* v){ delete v; }
int main() {
using Ptr = std::unique_ptr<int, void(&)(int*)>;
Ptr v(construct(), destruct);
}
当我使用 MSVC 19.33 构建 64 位二进制文件时,代码有效。如果我构建 32 位二进制文件,则会出现错误。
example.cpp
<source>(8): error C2660: 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr': function does not take 2 arguments
C:/data/msvc/14.33.31631/include\memory(3291): note: see declaration of 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr'
Compiler returned: 2
如果我在
__stdcall
中明确命名 std::unique_ptr<int, void(__stdcall&)(int*)>
,它与两者一起工作,所以我假设它是函数签名的一部分。
为什么 32 位和 64 位会有这种差异?这是编译器中的错误吗?
通过 MS 文档
在 ARM 和 x64 处理器上,__stdcall 被 编译器;在 ARM 和 x64 架构上,按照惯例,参数是 尽可能在寄存器中传递,并传递后续参数 在堆栈上。
所以
__stdcall
被 64 位编译器忽略,但仅对 32 位编译器有意义。