2012-01-30 18 views
0

基本的に私はOpenNI KinectをRTミドルウェアフレームワークにパックしようとしています。 OpenNI Kinectはコールバックを使用して登録する必要があります。C++ OOP登録コールバック関数(typedef issue)

これを行うには、問題なくグローバルにコールバック関数と関連する変数を宣言できます。

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

[簡単に述べる](http://stackoverflow.com/a/9063476/594137)[\ [33 \]メンバー関数へのポインタ](http://www.parashift .com/C++ - faq-lite/pointers-to-members.html)。 –

答えて

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パラメータを使用して、それへのポインタの周りに渡す必要があります。

+0

仕事の机に戻って静的な問題を試みるだけでなく、Styneのリンクを読んで、私はこの問題に取り組んでいます。PS:私の投稿に返信しても通知はありませんでした。私はこの質問を別のフォーラムに再掲載していたことを謝ります。私はいくつか試した後、ここに戻ってきます。再度、感謝します。 – hong

+0

jamesdlin、styne666、ポインタのおかげで!私は今問題を見ていますが、解決方法はわかりません。 Ya、staticは動作しますが、関連する変数は静的/グローバルでなければなりません。つまり静的関数はメンバー変数にアクセスできません。全体的な使用とグローバルな使用との違いはほとんどありません。私は現在、仕事をするために(構造体またはクラス)をラップする方法を勉強しています。現在完全に空白です。インターネットの有用なもの(海よりも大きい)を見つけることを願っています。どのポインタも非常に高く評価されます。もう一度、ありがとう! – hong

+0

@hong:私が言及したように、おそらく 'pCookie'パラメータの変数を含む' struct'/'class'へのポインタを渡したいと思うでしょう。コールバックを登録するときの典型的な方法です。 – jamesdlin

関連する問題