c++ - 回调函数中的参数顺序
问题描述
我正在观看此 C++Con 演讲https://www.youtube.com/watch?v=e8SyxB3_mnw&t=2933s&ab_channel=CppCon ,其中给出了类似以下代码的内容(https://godbolt.org/z/av4Tbn):
struct Handler {
void handle(int x, int y, int z);
static void callback0(void *instance, int x, int y, int z) {
static_cast<Handler *>(instance)->handle(x, y, z);
}
static void callback1(int x, int y, int z, void *instance) {
static_cast<Handler *>(instance)->handle(x, y, z);
}
};
auto c0 = Handler::callback0;
auto c1 = Handler::callback1;
该代码生成以下程序集:
Handler::callback0(void*, int, int, int):
jmp Handler::handle(int, int, int)
Handler::callback1(int, int, int, void*):
mov r8d, edi
mov rdi, rcx
mov ecx, edx
mov edx, esi
mov esi, r8d
jmp Handler::handle(int, int, int)
c1:
.quad Handler::callback1(int, int, int, void*)
c0:
.quad Handler::callback0(void*, int, int, int)
显然,回调 0 是这里的首选版本,但我不明白回调 1 中“幕后”发生了什么?有人可以详细说明吗?
解决方案
在callback0()
中,参数是通过 CPU 寄存器以handle()
期望它们的确切顺序传递的,其中instance
变为handler
的this
指针,因此无需重新排列任何值,因此为什么要单独jmp
使用。
在callback1
中,参数必须重新排列到handle()
期望它们的正确 CPU 寄存器中,jmp
然后才能调用。
这与在各种调用约定中传递参数的工作方式有关。
推荐阅读
- java - Spring Boot 应用程序中的 Spring SAML 2.0 在启动嵌入式 tomcat 时导致 MetadataManager 中出现 NullPointerException
- javascript - 单击其他位置时关闭侧边菜单
- javascript - 最快的字符串包含签入数组以获取 JS 中的大量数据
- python - Django - 模型元选项 app_label 不起作用
- sql - 为什么id序列主键不断变化?
- html - Flexbox 不会垂直居中父元素的子元素
- haskell - Haskell 中的 Lambda 抽象模式匹配
- javascript - 通过 axios 发送数据时 Multer req.files 未定义,但使用 Postman 时一切正常
- python-3.x - 如何获取 Javascript 生成的内容
- xml - 在 XQuery 中检查多个项目时返回一个真/假