当前位置:  开发笔记 > 前端 > 正文

动态调用带有varargs参数的C函数

如何解决《动态调用带有varargs参数的C函数》经验,为你挑选了2个好方法。

我正在使用C编程来对抗第三方库(在HP/Mercury Loadrunner中),该库为其中一个函数提供了varargs样式的可变大小参数列表.我想调用这个函数,但我不知道我将拥有多少个参数.

我的一个前任所做的功能在某种程度上起了作用,但这里的问题是这个函数假定最坏的情况(超过3000个参数)和手动代码.

为了阐明,这是代码的(开头).我们称之为的功能是web_submit_data().HTTP将发布一组表单数据.在处理具有任意数量字段的动态生成的表单时,会出现此实现.(从原版中清理了一下,手动编码索引也是如此......)


web_submit_data_buffer_gazillion_items( const char *bufferName, const char *bufferValue)
{
    const int size = 129;
    int i = 0;
    int j = 11;

    web_submit_data(&bufferName[i++ * size], //"some form"
                &bufferName[i++ * size], //"Action=https://blah.blah/form");
                &bufferName[i++ * size], //"Method=POST");
                &bufferName[i++ * size], //"TargetFrame=");
                &bufferName[i++ * size], //"RecContentType=text/html");
                &bufferName[i++ * size], //"Referer=https://blah.blah/index.html");
                &bufferName[i++ * size], //"Snapshot=t1.inf");
                &bufferName[i++ * size], //"Mode=HTML");
                ITEMDATA,  // missing in action: indexes 8 through 10
                &bufferName[j * size],&bufferValue[j++ * size], ENDITEM, 
                &bufferName[j * size],&bufferValue[j++ * size], ENDITEM, 
                &bufferName[j * size],&bufferValue[j++ * size], ENDITEM, 
..
(repeat the last 3 lines ad nauseum)
..
                &bufferName[j * size],&bufferValue[j++ * size], ENDITEM,
                &bufferName[j * size]);  
}

现在我找到了一个可能有用的外部库(http://www.dyncall.org),但我宁愿不a)完全依赖于处理器和b)尝试教Loadrunner关于外部源的链接.

编辑:原始函数使用硬编码索引而不是使用变量.如果结果太难以预测,仍然可以恢复原状.但是,由于我不太可能使用不同的编译器或硬件/操作系统来运行它,我怀疑它真的值得.

另外:我无法控制web_submit_data()的实现.所以只是将问题推到一个水平并不会削减它..

还有一点需要注意:规范web_submit_data()使用一个名为LAST的常量来标记参数列表的结尾.原始实现不使用它.据推测,呼叫网站确实......



1> Sherm Pendle..:

在CamelBones中,我使用libffi来调用objc_msgSend(),这是一个varargs函数.工作一种享受.



2> Ben..:

变长参数基本上只是指向传递给所​​需函数的一堆打包数据的指针.被调用函数负责解释此打包数据.

这种架构安全的方法是使用va_list宏(提到n-alexander),否则你可能会遇到各种数据类型在内存中填充的问题.

设计varargs函数的正确方法是实际上有两个版本,一个接受'...',然后提取va_list并将其传递给一个带有va_list的函数.这样,您可以根据需要动态构造参数,而可以调用该函数的va_list版本.

大多数标准IO函数都有varargs版本:vprintf for printf,vsprintf for sprintf ...你明白了.查看您的库是否实现了名为"vweb_submit_data"的函数或类似的效果.如果他们不这样做,请给他们发电子邮件并告诉他们修理他们的库.

3000条相同的东西(即使它是预处理器引起的)让我感到畏缩

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有