2017-12-28 36 views
0
// a.h 
typedef void (*DispatchFn)(void); 

struct cmd { 
    static const DispatchFn DISPATCH_FUNCTION; 
    int ID; 
}; 


// a.cpp 
void Foo() 
{ 
} 

const DispatchFn cmd::DISPATCH_FUNCTION = &Foo; 

cmd *CmdObject = (cmd *)(BufferOfMemory); 
CmdObject->ID = 6969; 

void *PtrToCmdObj = (void *)CmdObject; 

void Process() 
{ 
    DispatchFn Fn1 = ((cmd *)(PtrToCmdObj))->DISPATCH_FUNCTION; // <-- This points to DISPATCH_FUNCTION 
    Fn1(); 

    DispatchFn Fn2 = (DispatchFn)(PtrToCmdObj); // <-- This doesn't points to DISPATCH_FUNCTION, but points to ID 
    Fn2(); 
} 

Fn2は、staticデータメンバーですので、DISPATCH_FUNCTIONを指さないことをご理解ください。私は多くの異なるタイプのcmdを持っていますので、にアクセスする特定のタイプにPtrToCmdObjをキャストできません。void *をキャストして構造体の静的データメンバーにアクセスするにはどうすればよいですか?

私はvoid*DispatchFnにタイプをキャストし、私は、テンプレートを使用することを好む一般的な何かをする必要がある場合は

+1

いいえ、ありません。 [Yを手に入れたので、あなたのXは何ですか?](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – StoryTeller

+1

最初のケースでは、ポインタ自体は無関係で、その型だけが重要です。基本的には 'cmd :: DISPATCH_FUNCTION'と同じです。事前に 'cmd'の型を知らなくても、その静的メンバー関数を見つける方法はありません。 C++には反射機構が組み込まれていません。 – VTT

答えて

0

事前cmdの種類を知らなくてもDISPATCH_FUNCTIONを呼び出すことができる方法はあります。

// a.h 
    typedef void(*DispatchFn)(void); 
    /* your template extension for static method dispatching */ 
    template <class T> 
    struct callable 
    { 
    void operator()() 
    { 
     T::DISPATCH_FUNCTION(); 
     // or if u have non static class member then use this line 
     // static_cast<T*>(this)->NONSTATIC_DISPATCH_FUNCTION(); 
    } 
    }; 

    struct cmd : public callable<cmd> { 
    static const DispatchFn DISPATCH_FUNCTION; 
    int ID; 
    }; 

    // a.cpp 
    void Foo() 
    { 
    printf("%s", __FUNCTION__); 
    } 

    const DispatchFn cmd::DISPATCH_FUNCTION = &Foo; 

    template <class T> 
    void Process(T *PtrToCmdObj) 
    { 
    (*PtrToCmdObj)(); // <-- This will call DISPATCH_FUNCTION 
    } 

    void run() { 
    cmd *CmdObject = (cmd *)(BufferOfMemory); 
    CmdObject->ID = 6969; 

    Process(CmdObject); 
    } 

Processメソッドテンプレートを作成することによって、operator()オーバーロードを提供する任意の型の変数を呼び出す必要があります。

関連する問題