首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  C/C++/Obj-C

如何将 list 转换成可变长参数?

  •  
  •   icemanpro · 263 天前 · 1310 次点击
    这是一个创建于 263 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现有一函数 void foo(int count,...) ,因参数长度是在运行时才确定的,现将参数放入到一 list 中,如何调用 foo ,并将 list 做为参数传给 foo?
    11 回复  |  直到 2019-01-29 16:54:06 +08:00
        1
    eritpchy   263 天前
    直接传递 va_list 会好点
        2
    GeruzoniAnsasu   263 天前
    本来想说不能这么传

    然后再看了几遍。。。。foo 是已存在已定义不可改的接口吗。。那我觉得没有写法能帮你

    va_list 在 x64 上没法用
        3
    icyalala   263 天前
    试试 libffi
    @GeruzoniAnsasu va_list 在 x64 上为什么没法用?
        4
    GeruzoniAnsasu   263 天前
    @icyalala 其实是不太想解释

    首先如果是传参数进来,在函数里用 va_系列宏去解开传进来的变长参数,是可以用的,因为 x64 默认的 fastcall 约定虽然用寄存器传参,但会在栈上放一个副本,还是有地址可引用。不过放副本这个操作是被调函数的 prologue 做的,从外面打包参数进来的时候前 4 个参数还是只会通过寄存器传递。

    如果非要 hack 的话确实可以内嵌一下汇编先把前 4 个参数放进寄存器其余的压栈,但这样 hack 的话连 call 也必须要用汇编嵌进去并且返回后手动 add rsp 恢复栈平衡,更要命的是在 win 和 linux 上同样是 fastcall 约定用到的寄存器还不一样,还得针对平台写两套汇编

    虽然总共代码也不多,但总觉得崩的可能性太大了,想强迫 lz 先想其它的方法解决
        5
    GeruzoniAnsasu   263 天前
    啊。。。原来 fastcall 是用 6 个寄存器
        6
    icyalala   263 天前
    @GeruzoniAnsasu calling convention 不单只有 fastcall,参数也不单是 integer 类型,没必要重新实现一遍 libffi 嘛。。
        7
    catror   263 天前
        8
    enenaaa   263 天前
    @GeruzoniAnsasu 不定参数调用使用__cdecl 方式吧。 跟 fastcall 有啥关系。
        9
    pursuer   263 天前
    @enenaaa
    x86_64 操作系统规定的 abi 好像已经统一成类似 fastcall 的寄存器传参了,而且不同操作系统的 abi 还不一样
        10
    GeruzoniAnsasu   263 天前
    @icyalala
    @catror
    @enenaaa
    可以理解为,x64 只有一种调用约定,但有两个不同平台版本的实现
    尝试在编译到 x64 的源码函数上声明 stdcall 或 cdecl 都会被编译器忽略

    另外不定参函数这种东西,在 C++中必定是与变参模板同时存在的,在 C 中,变参函数实际上就是变参泛型的 approach, “运行时不定个数”类的东西不会用变参函数来写,一定会封装成某种数据结构并把指针传进去。无论 C 还是 C++,变参函数都是用来方便“静态不定个数参数的调用”的,C++通过变参模板给它加了更强的约束而已。

    所以最开始就想说,参数不能像 lz 设想的那样传,传一个“运行时不定长”的东西给变参函数本来就是错误的做法
        11
    eritpchy   263 天前
    https://stackoverflow.com/a/3968787
    代码虽丑但可以解决问题
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1841 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 01:33 · PVG 09:33 · LAX 18:33 · JFK 21:33
    ♥ Do have faith in what you're doing.