如何转换void *来访问结构的静态数据成员?

时间:2017-12-28 06:08:39

标签: c++ struct casting

// 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并不指向DISPATCH_FUNCTION,因为它是static数据成员。我有许多不同类型的cmd,因此我无法将PtrToCmdObj投射到特定类型以访问DISPATCH_FUNCTION

我有什么方法可以将void*转换为DispatchFn类型并在事先不知道DISPATCH_FUNCTION类型的情况下调用cmd

1 个答案:

答案 0 :(得分:0)

如果我需要做一些通用的事情,我更喜欢使用模板。

  // 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()重载的任何类型的变量进行调用。