基本上我正在尝试将OpenNI Kinect打包到RT中间件框架中。 OpenNI Kinect使用回调并且必须注册。
为此,我可以在没有问题的情况下在全局声明回调函数和相关变量。
// -----------------------------------------------
// Global
// ----------------------------------------------
// Declare OpenNI nodes
xn::Context g_Context;
xn::ScriptNode g_scriptNode;
xn::DepthGenerator g_DepthGenerator;
xn::UserGenerator g_UserGenerator;
// ... more codes
// Define callback functions
// Callback: New user was detected
void User_NewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
{
// ... some codes
if (g_bNeedPose)
{
g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
}
// ... some codes
}
// Callback: An existing user was lost
void User_LostUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
{
// ... some codes
}
// -----------------------------------------------
// Member
// ----------------------------------------------
// Register callback functioins in the RT-middleware class (OOP)
RTC::ReturnCode_t rtc_kinect::onActivated(RTC::UniqueId ec_id)
{
// ... some codes
nRetVal = g_UserGenerator.RegisterUserCallbacks(User_NewUser, User_LostUser, NULL, hUserCallbacks);
// ... some codes
}
以上工作。但是,有人告诉我,使用全局变量和函数是不合适的。
我试图将回调函数和相关变量作为中间件类的成员移动,但是不成功。代码是:
// ----------------------------------------
// private members
// ----------------------------------------
// Declare OpenNI nodes as member variables
xn::Context g_Context;
xn::ScriptNode g_scriptNode;
xn::DepthGenerator g_DepthGenerator;
xn::UserGenerator g_UserGenerator;
// ... more codes
// Define callback functions as member function
// Callback: New user was detected
void XN_CALLBACK_TYPE rtc_kinect::User_NewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
{
// ... some codes
if (g_bNeedPose)
{
g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
}
else
{
g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
}
}
// Callback: An existing user was lost
void XN_CALLBACK_TYPE rtc_kinect::User_LostUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
{
// ... some codes
}
// Register callback functioins in the RT-middleware class
RTC::ReturnCode_t rtc_kinect::onActivated(RTC::UniqueId ec_id)
{
// ... some codes
nRetVal = g_UserGenerator.RegisterUserCallbacks(&rtc_kinect::User_NewUser, &rtc_kinect::User_LostUser, NULL, hUserCallbacks);
// ... some codes
}
编译器报告了以下错误:
error C2664: 'xn::UserGenerator::RegisterUserCallbacks' : cannot convert parameter 1 from 'void (__stdcall rtc_kinect::* )(xn::UserGenerator &,XnUserID,void *)' to 'xn::UserGenerator::UserHandler'
error C2664: 'xn::PoseDetectionCapability::RegisterToPoseDetected' : cannot convert parameter 1 from 'void (__stdcall rtc_kinect::* )(xn::PoseDetectionCapability &,const XnChar *,XnUserID,void *)' to 'xn::PoseDetectionCapability::PoseDetection'
.... and many more
这是回调注册函数定义的一个示例:
inline XnStatus RegisterUserCallbacks(UserHandler NewUserCB, UserHandler LostUserCB, void* pCookie, XnCallbackHandle& hCallback)
{
// ... some codes
}
这是参数1的typedef的一个例子:
typedef void (XN_CALLBACK_TYPE* UserHandler)(UserGenerator& generator, XnUserID user, void* pCookie);
我的开发平台是MS Visual Studio 2008。 作为新手,我无法解决问题。希望得到任何帮助。
答案 0 :(得分:4)
回调是指向函数的指针。您正在尝试使用指向成员函数的指针。他们不是一回事。 (来自comp.lang.c ++ FAQ:Is the type of "pointer-to-member-function" different from "pointer-to-function"?)。成员函数需要在该类的对象上运行。
如果您改为使用函数static
类方法,则可以解决编译错误。
顺便说一下,你没有做太多工作来避免使用全局变量。 那是真正的问题;您的回调函数是否在全局范围内并不重要(特别是因为您可以将它们放在匿名命名空间中或使用static
关键字将它们限制为仅限于该文件的编译单元)。请注意,使用static
成员变量与使用全局变量没有任何不同。
我不熟悉此SDK,但您可能应该将所需的任何信息打包到struct
或class
中,并可能通过void* pCookie
参数传递指向它的指针。