我想知道如何在C++范围内实现AVR ICALL指令。假设我有一个指针变量来保存函数的地址,并且我希望另一个函数通过变量中保存的指针间接调用该函数。
预先感谢您的帮助和协助。
您只需将函数指针作为参数传递给函数,然后像往常一样调用它:
int call_pf (int (*pf)(int))
{
return pf (1);
}
有时,人们发现函数指针声明的语法令人困惑,并且如果可能的话他们会使用 typedef:
typedef int (*func_t)(int);
using fun_p = int (*)(int); // C++ only
然后照常使用
func_t
或 fun_p
:
int call2_pf (func_t pf)
{
return pf (2);
}
要获取函数的地址,只需使用不带参数的名称:
int inc (int i)
{
return i + 1;
}
int main (void)
{
return call1_pf (inc) + call2_pf (inc);
}
根据上下文和控制器,avr-gcc 可以使用
icall
、eicall
、ijmp
、eijmp
或 push/push/ret
序列来实现间接(尾)调用。当编译器可以在运行时计算出函数地址时,它可能会将间接调用转换为直接调用。
在C++中,当获取非静态方法的地址时,为了调用它,需要适当类型的对象来执行调用,并且必须使用运算符
->*
或.*
来调用:
struct S
{
int s;
int meth (int i) const { return s + i; }
};
int fun_S (const S *s, int (S::*fun)(int) const)
{
return (s ->* fun) (1);
}
int fun_S (const S &s, int (S::*fun)(int) const)
{
return (s .* fun) (1);
}
int call_fun_S (const S &s)
{
return fun_S (s, &S::meth) + fun_S (&s, &S::meth);
}