我正在尝试在C++应用程序中使用C库,并在以下情况下找到了自己(我知道我的C,但我对C++很新).在C方面,我有一组函数,它们以函数指针作为参数.在C++方面,我有一个带有仿函数的对象,它与C函数所需的函数指针具有相同的签名.有没有办法使用C++仿函数作为函数指针传递给C函数?
Tom*_*icz 53
您不能直接将指向C++仿函数对象的指针作为指向C代码的函数指针(甚至是C++代码).
另外,为了将回调移植到C代码,它至少需要声明extern "C"为非成员函数.至少,因为某些API需要特定的函数调用约定,因此需要额外的声明修饰符.
在许多环境中,C和C++具有相同的调用约定,仅在名称修改方面有所不同,因此任何全局函数或静态成员都可以使用.但是你仍然需要operator()在正常的函数中包含调用.
如果你的仿函数没有状态(它只是满足一些形式要求的对象):
class MyFunctor {
// no state
public:
MyFunctor();
int operator()(SomeType ¶m) const;
}
Run Code Online (Sandbox Code Playgroud)
你可以编写一个普通的extern"C"函数来创建函子并执行它的operator().
extern "C" int MyFunctorInC(SomeType *param)
{
static MyFunctor my_functor;
return my_functor(*param);
}
Run Code Online (Sandbox Code Playgroud)如果您的仿函数具有状态,例如:
class MyFunctor {
// Some fields here;
public:
MyFunctor(/* some parameters to set state */);
int operator()(SomeType ¶m) const;
// + some methods to retrieve result.
}
Run Code Online (Sandbox Code Playgroud)
并且 C回调函数采用某种用户状态参数(通常为void*):
void MyAlgorithmInC(SomeType *arr,
int (*fun)(SomeType *, void *),
void *user_state);
Run Code Online (Sandbox Code Playgroud)
你可以编写一个普通的extern"C"函数,它将状态参数转换为你的仿函数对象:
extern "C" int MyFunctorInC(SomeType *param, void *user_state)
{
MyFunctor *my_functor = (MyFunctor *)user_state;
return (*my_functor)(*param);
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
MyFunctor my_functor(/* setup parameters */);
MyAlgorithmInC(input_data, MyFunctorInC, &my_functor);
Run Code Online (Sandbox Code Playgroud)否则唯一正常的方法(正常情况,如"在运行时不生成机器代码"等)是使用一些静态(全局)或线程本地存储将仿函数传递给extern"C"函数.这限制了你可以用你的代码做什么,并且很丑陋但会起作用.
不,当然.C函数的签名将参数作为函数.
void f(void (*func)())
{
func(); // Only void f1(), void F2(), ....
}
Run Code Online (Sandbox Code Playgroud)
所有带仿函数的技巧都由模板函数使用:
template<class Func>
void f (Func func)
{
func(); // Any functor
}
Run Code Online (Sandbox Code Playgroud)