c++:调用一个函数,并将不同数量的参数存储在数组中?
我有一个带有签名 double func(double,...)
的函数,并且我确信传递给 func 的所有参数都是 double 类型。所有参数都存储在一些称为参数的向量中,我只是想知道是否有方法编写通用代码以将 argumentVector 中指定的任意数量的参数传递给 func?
像这样的东西:
for (int i=0;i<agumentVector.size();i++)
pushstack(argumentVector[i]);
res = call(func);
到目前为止我已经尝试过这段代码,但它似乎有问题:
double* param = &argumentVector[0];
for(int i=0;i<argumentVector.size();i++)
{
_asm sub esp,8;
_asm fld param;
_asm fstp qword ptr [esp];
param++;
}
_asm call func;
_asm add esp,10h;
_asm fstp qword ptr res;
--我得到的只是一个疯狂的结果!这段代码运行没有任何问题:
double x[2] = {5,6};
double *param = x;
double res;
_asm sub esp,8;
_asm fld x;
_asm fstp qword ptr [esp];
_asm sub esp,8;
_asm fld x+8;
_asm fstp qword ptr [esp];
param++;
_asm call p;
_asm add esp,10h;
_asm fstp qword ptr res;
cout << res << "\n";
虽然在这一点中参数没有正确传递!
double x[2] = {5,6};
double *param = x;
double res;
_asm sub esp,8;
_asm fld param;
_asm fstp qword ptr [esp];
_asm sub esp,8;
_asm fld param+8;
_asm fstp qword ptr [esp];
param++;
_asm call p;
_asm add esp,10h;
_asm fstp qword ptr res;
cout << res << "\n";
你知道为什么吗?我虽然 x 和 param 都是简单的数组!
--edit2--
这是迄今为止 VC 生成的完整汇编代码
double x[2] = {5,6};
010E1A05 fld qword ptr [__real@4014000000000000 (10EB928h)]
010E1A0B fstp qword ptr [ebp-48h]
010E1A0E fld qword ptr [__real@4018000000000000 (10EB878h)]
010E1A14 fstp qword ptr [ebp-40h]
double *param = x;
010E1A17 lea eax,[ebp-48h]
010E1A1A mov dword ptr [ebp-54h],eax
double res;
p(param[0],param[1]);
010E1A1D mov esi,esp
010E1A1F mov eax,dword ptr [ebp-54h]
010E1A22 sub esp,8
010E1A25 fld qword ptr [eax+8]
010E1A28 fstp qword ptr [esp]
010E1A2B mov ecx,dword ptr [ebp-54h]
010E1A2E sub esp,8
010E1A31 fld qword ptr [ecx]
010E1A33 fstp qword ptr [esp]
010E1A36 call dword ptr [ebp-14h]
010E1A39 fstp st(0)
010E1A3B add esp,10h
010E1A3E cmp esi,esp
010E1A40 call @ILT+795(__RTC_CheckEsp) (10E1320h)
{
_asm sub esp,8;
010E1A45 sub esp,8
_asm fld param+8;
010E1A48 fld dword ptr [ebp-4Ch]
_asm fstp qword ptr [esp];
010E1A4B fstp qword ptr [esp]
_asm sub esp,8;
010E1A4E sub esp,8
_asm fld param;
010E1A51 fld dword ptr [ebp-54h]
_asm fstp qword ptr [esp];
010E1A54 fstp qword ptr [esp]
}
_asm call p;
010E1A57 call dword ptr [ebp-14h]
_asm add esp,10h;
010E1A5A add esp,10h
_asm fstp qword ptr res;
010E1A5D fstp qword ptr [ebp-64h]
cout << res << "\n";
010E1A60 push offset string "\n" (10EB834h)
010E1A65 mov esi,esp
010E1A67 sub esp,8
010E1A6A fld qword ptr [ebp-64h]
010E1A6D fstp qword ptr [esp]
010E1A70 mov ecx,dword ptr [__imp_std::cout (10EF3A8h)]
010E1A76 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (10EF3ACh)]
010E1A7C cmp esi,esp
010E1A7E call @ILT+795(__RTC_CheckEsp) (10E1320h)
010E1A83 push eax
010E1A84 call std::operator<<<std::char_traits<char> > (10E1294h)
010E1A89 add esp,8
return 0;
I've got a function with signature double func(double,...)
and I'm sure all the arguments I'm passing to func are type double. All arguments are stored in some a vector called arguments, I'm just wondering if there is way to write a generic code to pass any number of arguments specified in argumentVector to func?
something like :
for (int i=0;i<agumentVector.size();i++)
pushstack(argumentVector[i]);
res = call(func);
so far I've tried this code but it seems to have problems:
double* param = &argumentVector[0];
for(int i=0;i<argumentVector.size();i++)
{
_asm sub esp,8;
_asm fld param;
_asm fstp qword ptr [esp];
param++;
}
_asm call func;
_asm add esp,10h;
_asm fstp qword ptr res;
--just a crazy result I'm getting! this code runs without any problems :
double x[2] = {5,6};
double *param = x;
double res;
_asm sub esp,8;
_asm fld x;
_asm fstp qword ptr [esp];
_asm sub esp,8;
_asm fld x+8;
_asm fstp qword ptr [esp];
param++;
_asm call p;
_asm add esp,10h;
_asm fstp qword ptr res;
cout << res << "\n";
while in this one arguments are not passed properly!
double x[2] = {5,6};
double *param = x;
double res;
_asm sub esp,8;
_asm fld param;
_asm fstp qword ptr [esp];
_asm sub esp,8;
_asm fld param+8;
_asm fstp qword ptr [esp];
param++;
_asm call p;
_asm add esp,10h;
_asm fstp qword ptr res;
cout << res << "\n";
do you have any idea why? I though both x and param were simple arrays!
--edit2--
here is the complete assembly code so far VC generates
double x[2] = {5,6};
010E1A05 fld qword ptr [__real@4014000000000000 (10EB928h)]
010E1A0B fstp qword ptr [ebp-48h]
010E1A0E fld qword ptr [__real@4018000000000000 (10EB878h)]
010E1A14 fstp qword ptr [ebp-40h]
double *param = x;
010E1A17 lea eax,[ebp-48h]
010E1A1A mov dword ptr [ebp-54h],eax
double res;
p(param[0],param[1]);
010E1A1D mov esi,esp
010E1A1F mov eax,dword ptr [ebp-54h]
010E1A22 sub esp,8
010E1A25 fld qword ptr [eax+8]
010E1A28 fstp qword ptr [esp]
010E1A2B mov ecx,dword ptr [ebp-54h]
010E1A2E sub esp,8
010E1A31 fld qword ptr [ecx]
010E1A33 fstp qword ptr [esp]
010E1A36 call dword ptr [ebp-14h]
010E1A39 fstp st(0)
010E1A3B add esp,10h
010E1A3E cmp esi,esp
010E1A40 call @ILT+795(__RTC_CheckEsp) (10E1320h)
{
_asm sub esp,8;
010E1A45 sub esp,8
_asm fld param+8;
010E1A48 fld dword ptr [ebp-4Ch]
_asm fstp qword ptr [esp];
010E1A4B fstp qword ptr [esp]
_asm sub esp,8;
010E1A4E sub esp,8
_asm fld param;
010E1A51 fld dword ptr [ebp-54h]
_asm fstp qword ptr [esp];
010E1A54 fstp qword ptr [esp]
}
_asm call p;
010E1A57 call dword ptr [ebp-14h]
_asm add esp,10h;
010E1A5A add esp,10h
_asm fstp qword ptr res;
010E1A5D fstp qword ptr [ebp-64h]
cout << res << "\n";
010E1A60 push offset string "\n" (10EB834h)
010E1A65 mov esi,esp
010E1A67 sub esp,8
010E1A6A fld qword ptr [ebp-64h]
010E1A6D fstp qword ptr [esp]
010E1A70 mov ecx,dword ptr [__imp_std::cout (10EF3A8h)]
010E1A76 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (10EF3ACh)]
010E1A7C cmp esi,esp
010E1A7E call @ILT+795(__RTC_CheckEsp) (10E1320h)
010E1A83 push eax
010E1A84 call std::operator<<<std::char_traits<char> > (10E1294h)
010E1A89 add esp,8
return 0;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下内容在 Visual Studio 中有效,但我认为您可以轻松更正内联汇编器语法,使其满足编译器的要求。
The following works in Visual Studio, but I think you can easily correct the inline assembler syntax so it fits your compiler's requirements.
根据我的具体要求,我会执行您在下面看到的这两个操作之一。使用 Assembly 将是我的选项列表中的最后一个。
操作。 1 如果所有参数都属于同一类型,为什么不只传递向量呢?它是类型安全的,并且不会像使用可变长度参数列表时那样溢出。请记住,如果您只希望函数使用向量的一部分,您也可以传递开始和结束迭代器。
操作。 2 如果您的参数属于不同类型,请使用 Boost .任意。
Depending on my specific requirements, I'd do one of these two you see below. Using Assembly would be last on my list of options.
Op. 1 If all your arguments are of the same type, why not just pass the vector? It's type safe and you can't overflow like when you use variable length argument lists. Remember that you can also pass beginning and ending iterators if you only want the function to use a part of the vector.
Op. 2 If your arguments are of different types, use Boost.Any.
您是否以正确的相反顺序推送这些值?
如果你有
void func(int a, int b, int c)
你必须这样做:
如果你只想嵌入程序集,并且它完全按照你放置的方式执行:
但在执行此操作之前,请确保这确实是一种优化,而不是一个不成熟的优化。
Are you pushing the values in the correct reversed order?
If you have
void func(int a, int b, int c)
you have to do:
If you just want to embed assembly, and be it executed exactly as you placed it:
But before doing this, be sure that it is indeed an optimization, and not a premature one.