2017-12-28 18 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(); 
} 

Fn2static 데이터 멤버이므로 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); 
    } 

처리 메소드 템플릿을 작성하면 operator() 오버로드를 제공하는 모든 유형의 변수를 호출해야합니다.

관련 문제