我在C++应用程序中使用C库.C SDK具有将回调函数指针作为参数的函数.这些功能的签名通常如下:
typedef int (* Func) (type1 c, type2 d);
Run Code Online (Sandbox Code Playgroud)
我的代码是用C++中的类构建的.但是,我不能将任何成员函数作为回调传递给此函数,因为它不接受int (MyClass::*)(type1 c, type2 d)并且只接受int (*)(type1 c, type2 d).
我通过static在各个类中定义所有回调,然后将它们传递给C库然后工作来解决这个问题.
我还是C++的新手,所以我不确定这是否是正确的解决方案?代码有效,但我很想知道我做错了.
在大多数平台上,您的代码可能会遇到,您的解决方案很好.但是,严格地说,可以有一个C调用约定和C++调用约定不同的平台.在这个平台上,你的代码不起作用.
100%正确的解决方案(与您使用的99.9%正确的解决方案相对)是使用C语言链接定义一个函数作为回调.如果您需要此函数来获得对您的类的成员访问权限,则可以static在您的类中调用成员函数:
class MyClass
{
static int secret;
public:
static void callback() { secret = 42; }
};
extern "C" void callback() { MyClass::callback(); }
Run Code Online (Sandbox Code Playgroud)
请注意,对于回调注册点的作者(即,将向您回调的库的作者)来说,为用户提供了一种void*与回调相关联的数据的方法被认为是一种良好的做法,该回调将在他们调用您时传入.如果您的库允许,您可以使用它void *user_data来传递指向C++类的指针.有了这样一个设计精美的回调库,它看起来像这样:
class MyClass
{
int secret;
public:
void setSecret() { secret = 42; }
};
extern "C" void callback(void *userData) { static_cast<MyClass*>(userData)->setSecret(); }
MyClass mc;
int main()
{
cLibrary_registerCallback(&callback, &mc);
}
Run Code Online (Sandbox Code Playgroud)