You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中像C一样声明带动态参数的汇编函数

C++中调用带可变参数的汇编函数问题解决

问题说明

将C代码移植到C时,调用一个位于单独asm文件、用于直接调用ntdll.dll系统调用的汇编函数时出现编译错误。C中无参数列表的函数声明默认支持可变参数,可正常调用;但C中extern "C" VOID asmFunc();的声明会严格检查参数数量,导致传入多参数时触发E0140 too many arguments in function call错误。

C版本正常代码

extern asmFunc(); // C中无参数列表的声明默认允许可变参数

// 调用示例
asmFunc(var1, ptr2, HANDLE); 
asmFunc(ptr4, var2, NULL, eg ...); // 正常运行

C++版本报错代码

extern "C" VOID asmFunc(); // C++中此声明表示函数无参数

// 调用示例
asmFunc(var1, ptr2, HANDLE); // 编译错误:E0140 参数过多
asmFunc(ptr4, var2, NULL, eg ...); // 编译错误:E0140 参数过多

解决方法

1. 修改函数声明为可变参数形式

直接将C++中的函数声明改为支持可变参数的写法,同时保留extern "C"确保C调用约定:

extern "C" void asmFunc(...);

这样编译器会允许传入任意数量的参数,行为和C中的声明完全一致。

2. 使用函数指针兼容

如果无法修改原始声明,可以通过函数指针来绕过参数检查:

// 定义支持可变参数的函数指针类型
typedef void (*AsmFuncPtr)(...);

// 关联到目标函数
extern "C" void asmFunc();
AsmFuncPtr funcPtr = reinterpret_cast<AsmFuncPtr>(&asmFunc);

// 通过指针调用,支持可变参数
funcPtr(var1, ptr2, HANDLE);
funcPtr(ptr4, var2, NULL, eg ...);

3. 确认并匹配调用约定

确保汇编函数使用支持可变参数的调用约定(如cdecl,该约定由调用者负责清理栈,适配可变参数场景):

  • C++声明明确指定调用约定:
    extern "C" void __cdecl asmFunc(...);
    
  • 汇编文件中对应设置调用约定(以MASM为例):
    PUBLIC _asmFunc
    _asmFunc PROC C ; C代表cdecl调用约定
        ; 汇编实现逻辑
    _asmFunc ENDP
    

内容的提问来源于stack exchange,提问作者user16658873

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:55:25