Pergunta

Basically I am trying to pack OpenNI Kinect into RT-middleware framework. The OpenNI Kinect uses callback and has to be registered.

To do this, I could declare the callback functions and relevant variables in global without problem.

// -----------------------------------------------
// 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
}

The above worked. However, using global variables and functions, I was told, is inappropriate.

I tried to move the callback functions and related variables as member of the middleware class, however been unsuccessful. The codes are:

// ----------------------------------------
// 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
}

The following errors were reported by the compiler:

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

This is one example of the definition of the callback registration function:

inline XnStatus RegisterUserCallbacks(UserHandler NewUserCB, UserHandler LostUserCB, void* pCookie, XnCallbackHandle& hCallback)
{
    // ... some codes
}

This an example of the typedef of the parameter 1:

typedef void (XN_CALLBACK_TYPE* UserHandler)(UserGenerator& generator, XnUserID user, void* pCookie);

My development platform is MS Visual Studio 2008. Being novice, I cannot resolve the problem. Hopeful for any help.

Foi útil?

Solução

The callbacks are meant to be pointers-to-functions. You're trying to use pointers-to-member-functions. They aren't the same thing. (From the comp.lang.c++ FAQ: Is the type of "pointer-to-member-function" different from "pointer-to-function"?). Member functions need to operate on an object of that class.

You can resolve your compilation error if you make your functions static class methods instead.

Incidentally, you didn't really do much to avoid using global variables. That is the real problem; it doesn't matter so much whether your callback functions are in the global scope or not (especially since you could put them in an anonymous namespace or use the static keyword to limit them to only that file's compilation unit). Note that using static member variables isn't really any different from using globals.

I'm not familiar with this SDK, but you probably should pack whatever information you need into a struct or class and presumably pass around pointer to it through that void* pCookie parameter.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top