1
eritpchy 2019-01-29 14:12:57 +08:00
直接传递 va_list 会好点
|
2
GeruzoniAnsasu 2019-01-29 14:16:44 +08:00
本来想说不能这么传
然后再看了几遍。。。。foo 是已存在已定义不可改的接口吗。。那我觉得没有写法能帮你 va_list 在 x64 上没法用 |
3
icyalala 2019-01-29 14:22:39 +08:00
试试 libffi
@GeruzoniAnsasu va_list 在 x64 上为什么没法用? |
4
GeruzoniAnsasu 2019-01-29 14:48:35 +08:00
@icyalala 其实是不太想解释
首先如果是传参数进来,在函数里用 va_系列宏去解开传进来的变长参数,是可以用的,因为 x64 默认的 fastcall 约定虽然用寄存器传参,但会在栈上放一个副本,还是有地址可引用。不过放副本这个操作是被调函数的 prologue 做的,从外面打包参数进来的时候前 4 个参数还是只会通过寄存器传递。 如果非要 hack 的话确实可以内嵌一下汇编先把前 4 个参数放进寄存器其余的压栈,但这样 hack 的话连 call 也必须要用汇编嵌进去并且返回后手动 add rsp 恢复栈平衡,更要命的是在 win 和 linux 上同样是 fastcall 约定用到的寄存器还不一样,还得针对平台写两套汇编 虽然总共代码也不多,但总觉得崩的可能性太大了,想强迫 lz 先想其它的方法解决 |
5
GeruzoniAnsasu 2019-01-29 14:55:07 +08:00
啊。。。原来 fastcall 是用 6 个寄存器
|
6
icyalala 2019-01-29 15:33:03 +08:00
@GeruzoniAnsasu calling convention 不单只有 fastcall,参数也不单是 integer 类型,没必要重新实现一遍 libffi 嘛。。
|
7
catror 2019-01-29 15:37:53 +08:00
|
8
enenaaa 2019-01-29 15:38:47 +08:00
@GeruzoniAnsasu 不定参数调用使用__cdecl 方式吧。 跟 fastcall 有啥关系。
|
9
pursuer 2019-01-29 15:48:40 +08:00
@enenaaa
x86_64 操作系统规定的 abi 好像已经统一成类似 fastcall 的寄存器传参了,而且不同操作系统的 abi 还不一样 |
10
GeruzoniAnsasu 2019-01-29 16:45:38 +08:00
@icyalala
@catror @enenaaa 可以理解为,x64 只有一种调用约定,但有两个不同平台版本的实现 尝试在编译到 x64 的源码函数上声明 stdcall 或 cdecl 都会被编译器忽略 另外不定参函数这种东西,在 C++中必定是与变参模板同时存在的,在 C 中,变参函数实际上就是变参泛型的 approach, “运行时不定个数”类的东西不会用变参函数来写,一定会封装成某种数据结构并把指针传进去。无论 C 还是 C++,变参函数都是用来方便“静态不定个数参数的调用”的,C++通过变参模板给它加了更强的约束而已。 所以最开始就想说,参数不能像 lz 设想的那样传,传一个“运行时不定长”的东西给变参函数本来就是错误的做法 |
11
eritpchy 2019-01-29 16:54:06 +08:00
https://stackoverflow.com/a/3968787
代码虽丑但可以解决问题 |