【问题标题】:How to cast a void* to access a static data member of a struct?如何强制转换 void* 来访问结构的静态数据成员?
【发布时间】:2018-06-08 16:50:53
【问题描述】:
// 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 类型并在事先不知道cmd 类型的情况下调用DISPATCH_FUNCTION

【问题讨论】:

  • 在第一种情况下,指针本身无关紧要,只有它的类型很重要。基本上和写cmd::DISPATCH_FUNCTION是一样的。如果事先不知道cmd 的类型,就无法定位其静态成员函数。 C++ 没有(内置)反射机制。

标签: c++ struct casting


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2019-08-25
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    相关资源
    最近更新 更多