我有一个功能
void foo(int cnt, va_list ap);
我需要使用它,但要求相当严格,va_list
的数量会有所变化,并且在运行时会发生变化。我想做的是:
创建一个va_list
(需要char*
)表单
QList<Contact*>
其中Contact
是已定义的类
class Contact
{
public:
QString getName();
private:
QString m_name;
};
我想在循环va_list
中填充,例如:
for (int idx = 0; idx<contacts.count(); idx++)
{
contacts.at(idx)->getName(); // this i would like to pass to va_list
}
有人知道我是怎么做到的吗?
7条答案
按热度按时间hc2pp10m1#
您需要做的是模拟调用堆栈,以便将构造的va_list传递给foo()。这是编译器所特有的(并且警告,即使是32位编译器和64位编译器之间也存在差异)。下面的代码***仅用于娱乐目的!!!***(如果它在你的系统上工作的话)它很容易被破坏。有了它,我使用一个平面内存缓冲区,然后用一个计数和一堆字符串填充它。你可以在适当的时候用指向你的字符串的指针填充它,然后把它们传下来。
它似乎确实可以在我的系统Windows 7 W/ Visual Studio 2008上工作,仅适用于32位应用程序。
错误的想法代码如下!!!
我现在要为想到这样的主意而羞愧地低下头去了。
f1tvaqid2#
...嗯...也许不方便携带...肯定不好...但可能会解决你的问题...
ef1yzkbh3#
你的问题被标记为C++,在C++中有很好的方法(比如流)来完全避免varargs。
这是一个很好的例子,说明了为什么va_args会导致痛苦。如果你有机会改变
foo
的签名,那是你最好的选择。用std::vector<std::string>
代替va_list正好解决了你的问题。如果
foo
在一个不能更改的外部库中,我的下一个建议是找到一个不同的库。如果这些都不是一个选项,那么似乎应该有一种方法使用va_list递归地构建调用列表,但是我不知道如何使其工作。
2ul0zpep4#
如果列表中的元素数量有限,我会根据元素数量选择手动调度。
1bqhqjot5#
您尝试使用的是
alloca
。va_list
对象不能存储变量,函数调用存储它们,并且您只能通过va_list访问它。这些变量仅在调用期间有效,之后它们将被重写。这将不起作用:
要在堆栈上分配内存,而不需要写变量函数,可以使用
alloca
,它的工作原理或多或少类似于malloc
,但你不需要调用free
,当你离开作用域时,它会自动释放自己。这和写作基本上是一样的
但是在
alloca
中,3不需要是常量,同样,你只能在封闭作用域内使用它,所以不要从函数中返回它。如果你想从va_list得到的是一个列表中的多个类型,考虑写一个如下的union:
3vpjnl9f6#
这取决于编译器,什么是va_list类型,什么是va_start和va_end宏。你不能用标准的方法来做这件事。你必须使用编译器特定的构造。
也许你可以改变'foo'函数?如果是这样的话,那么让它反向转换va_list到QList,并让'foo'接受QList。
//编辑
然后看看va_list类型是什么,在你的编译器中va_start和va_end宏是什么,然后用这些宏可以工作的方式构建你的va_list。
sy5wg1nm7#
〈只是为了好玩〉
〈/只是为了好玩〉