OO设计:多实例但静态回调 我试图在C++中包装C库。库定义了一些回调函数,例如void(*callback)(void*),显然,在我的OO类中,这些回调函数必须是静态的
我的问题是从回调函数中找到正确的类实例。在创建对象时,回调参数未知OO设计:多实例但静态回调 我试图在C++中包装C库。库定义了一些回调函数,例如void(*callback)(void*),显然,在我的OO类中,这些回调函数必须是静态的,c++,c,oop,callback,C++,C,Oop,Callback,我的问题是从回调函数中找到正确的类实例。在创建对象时,回调参数未知 class CObj { public: CObj() { c_lib_start(CObj::CallbackFunc); } static void CallbackFunc(void* arg) { c_lib_type* data = (c_lib_type*)arg; // ... handle data callback } } int main(int argc,
class CObj
{
public:
CObj()
{
c_lib_start(CObj::CallbackFunc);
}
static void CallbackFunc(void* arg)
{
c_lib_type* data = (c_lib_type*)arg;
// ... handle data callback
}
}
int main(int argc, char* argv[])
{
CObj obj1;
CObj obj2; // will call the same callback function as obj1! can this be avoided?
}
编辑:
经过思考,我的最佳解决方案草案如下:
class CObj
{
public:
CObj(void (*pFuncPtr)(void*))
{
c_lib_start(pFuncPtr);
}
void CallbackFunc(void* arg)
{
c_lib_type* data = (c_lib_type*)arg;
// ... handle data callback
}
}
// globals. templated?
CObj* g_obj1 = NULL;
void FuncPtr1(void* arg) { g_obj1->CallbackFunc(arg); }
CObj* g_obj2 = NULL;
void FuncPtr2(void* arg) { g_obj2->CallbackFunc(arg); }
int main(int argc, char* argv[])
{
g_obj1 = new CObj(FuncPtr1);
g_obj2 = new CObj(FuncPtr2);
}
一个有用的C回调函数有一个类似于
R函数(void*user\u data)
的签名,或者带有附加参数R函数(A0 A0,A1 A1,…AN,void*user\u data)
。C库应该提供一个类似register\u函数(函数类型,void*用户数据)的函数
这样,您可以通过调用ReistStyFalm(Ac::StasyPixMeMySuffic函数)登记C++对象和静态成员函数对。 在调用时,将用户数据强制转换为传递给注册的类对象
如果没有上面提到的,你就会进退两难。您将把调用对象存储在一个全局变量中,并在回调函数中使用它,从而使回调仅限于一个对象 您的编辑提出了以下想法:
template<size_t SerialNumber>
class CObjFactory
{
private:
static std::weak_ptr<CObj> weakObj;
static void CallbackFuncWrapper(void* arg)
{
auto strongObj = weakObj.lock();
if(strongObj == nullptr)
return;
strongObj->CallbackFunc(arg);
}
public:
static std::shared_ptr<CObj> Create()
{
auto strongObj = std::make_shared<CObj>(CallbackFuncWrapper);
weakObj = strongObj;
return strongObj;
}
};
template<size_t SerialNumber>
std::weak_ptr<CObj> CObjFactory<SerialNumber>::weakObj;
void main()
{
std::shared_ptr<CObj> o1 = CObjFactory<0>::Create();
std::shared_ptr<CObj> o2 = CObjFactory<1>::Create();
}
模板
类CObjFactory
{
私人:
静态标准:弱ptr weakObj;
静态void CallbackFuncWrapper(void*arg)
{
auto strongObj=weakObj.lock();
如果(strongObj==nullptr)
返回;
strong对象->调用函数(arg);
}
公众:
静态std::shared_ptr Create()
{
自动strongObj=std::使_共享(CallbackFuncWrapper);
weakObj=strongObj;
返回strongObj;
}
};
模板
标准::弱ptr CObjFactory::weakObj;
void main()
{
std::shared_ptr o1=CObjFactory::Create();
std::shared_ptr o2=CObjFactory::Create();
}
这当然是一种黑客行为,但我认为,考虑到您所受的限制,您会遇到黑客行为。如果
c_lib_type
有一个用于客户端提供数据的字段,您可以使用该字段。否则,恐怕你就不走运了。什么是c_lib_type
?回调可以在任何时候突然发生,还是只在应用程序执行某些涉及已知CObj实例的操作时发生?如果是后者,您可以求助于丑陋的解决方案,将静态CObj*currentThis
放入CObj中,并在触发回调之前将其设置为正确的值。@DieterLücking c_lib_类型是一种抽象数据类型,源自c库。@dlf回调可能随时发生。