我有主要更新,我在呼叫前进行访问控制。我想在我的代码中使用一个地方来调用任何紧急功能。
我有一个结构ACTION:
{
FUNC_PROTOTYPE pfnAction;
unsigned int argsnum;
va_list argsval;
};
当我需要调用func时,我会这样做:
1 将func和参数放入队列; 2 在下次更新时弹出它们
{
ACTION action;
while(!Queue_isEmpty())
{ // check and pop urgent functions
if(Queue_Pop(&action))
{
action.pfnAction(action.argsnum, action.args);
va_end(action.args);
}
}
}
例如,我尝试拨打
void func(unsigned int argsnum, va_list args)
但我在func中的 args 已损坏。
我想,当我从队列中弹出时出现了这个问题:
Queue_Pop(P_ACTION p_res)
{
if(!Queue_isEmpty())
{
p_res->pfnAction = header->pfnAction;
p_res->argsnum = header->argsnum;
if(0 < p_res->argsnum)
{
p_res->argsval = header->argsval;
va_end(header->argsval);
}
...
}
}
但 action.args没问题。
答案 0 :(得分:0)
您不能将vararg列表作为对象传递,甚至不能使用va_list
。这不起作用/是未定义的行为。
如果您正在使用C ++进行编程,那么(1)不要用C标记您的问题,并且(2)存储带有绑定参数的std::function
。
答案 1 :(得分:0)
正如@mSalters所说,你不能传递va_list - 它只在具有变量args的函数的堆栈帧中有效。
在严格传递堆栈的架构上,可能能够通过存储va_list指向的初始地址和遍历所有预期参数后的地址来破解它,然后复制所有两个地址之间的内存进入分配的缓冲区。这必须在排队之前完成。在队列弹出方面,你可以通过使va_list指向你的副本来伪造va_arg。
我不建议将此实际用于除实验之外的任何其他目的。
在许多现代架构中,这不起作用,因为一些变量也在寄存器中传递。有关va_args如何混乱的详细信息,请参阅this article。