【问题标题】:pointer type for buffer which contains multiple different types包含多种不同类型的缓冲区的指针类型
【发布时间】:2014-08-25 14:59:14
【问题描述】:

如果我想声明一个指向缓冲区的指针,并且该缓冲区包含多种不同的类型(int、char 等),那么我应该将指针指向哪种类型?无效*?

【问题讨论】:

  • 数据是如何存储的?二进制?你听说过TLV吗?
  • 我认为我们没有足够的信息来回答。例如,当您使用缓冲区时,如何确定内容的类型?无论如何,乍一看,似乎重新考虑设计可能是为了。
  • 我正在使用名为 Game Maker Studio 的程序将内容添加到缓冲区。我正在使用名为 buffer_write 的 GML(游戏制作语言)函数来存储数据。我正在使用buffer_get_address 获取缓冲区的地址并将地址传递给 DLL,以便我可以从 DLL 访问缓冲区。
  • GM Studio 只使用两种类型:“string”和“real”。我相信这些分别转化为 char 和 double。

标签: c++ pointers buffer


【解决方案1】:

是的void * 是通用指针。但是你应该谨慎使用它。如果你想使用一个库,那么boost 库的any 类型是一个安全的通用容器

【讨论】:

    【解决方案2】:

    根据您的描述,您似乎正在尝试将自己的不同类型的序列化设计到缓冲区中(在现实生活中,以可移植的方式做到这一点很困难,并且在大多数情况下,像protocol buffers 这样定义良好的序列化库可以解决问题)。

    在过去我使用自定义缓冲区管理的情况下,我见过人们管理缓冲区的三种方式

    1. void* 并仔细管理代码中的偏移量
    2. char* 并使用 char* 将是一个字节的事实。
    3. uint8_t* 作为一种从缓冲区读取数据字节的可移植方式。

    请记住,如果您分配缓冲区来管理不同类型的数据,您最终会仔细读取字节并将其转换为适当的类型。我喜欢第 3 种方法,它是一种从缓冲区读取字节并在进程中保持缓冲区中字节对齐的干净方式。

    【讨论】:

      【解决方案3】:

      在 windows 下,您可以使用 VARIANT。 在Linux下,可以复制相关

      struct tagVARIANT
          {
          union 
              {
              struct __tagVARIANT
                  {
                  VARTYPE vt;
                  WORD wReserved1;
                  WORD wReserved2;
                  WORD wReserved3;
                  union 
                      {
                      LONGLONG llVal;
                      LONG lVal;
                      BYTE bVal;
                      SHORT iVal;
                      FLOAT fltVal;
                      DOUBLE dblVal;
                      VARIANT_BOOL boolVal;
                      _VARIANT_BOOL bool;
                      SCODE scode;
                      CY cyVal;
                      DATE date;
                      BSTR bstrVal;
                      IUnknown *punkVal;
                      IDispatch *pdispVal;
                      SAFEARRAY *parray;
                      BYTE *pbVal;
                      SHORT *piVal;
                      LONG *plVal;
                      LONGLONG *pllVal;
                      FLOAT *pfltVal;
                      DOUBLE *pdblVal;
                      VARIANT_BOOL *pboolVal;
                      _VARIANT_BOOL *pbool;
                      SCODE *pscode;
                      CY *pcyVal;
                      DATE *pdate;
                      BSTR *pbstrVal;
                      IUnknown **ppunkVal;
                      IDispatch **ppdispVal;
                      SAFEARRAY **pparray;
                      VARIANT *pvarVal;
                      PVOID byref;
                      CHAR cVal;
                      USHORT uiVal;
                      ULONG ulVal;
                      ULONGLONG ullVal;
                      INT intVal;
                      UINT uintVal;
                      DECIMAL *pdecVal;
                      CHAR *pcVal;
                      USHORT *puiVal;
                      ULONG *pulVal;
                      ULONGLONG *pullVal;
                      INT *pintVal;
                      UINT *puintVal;
                      struct __tagBRECORD
                          {
                          PVOID pvRecord;
                          IRecordInfo *pRecInfo;
                          }   __VARIANT_NAME_4;
                      }   __VARIANT_NAME_3;
                  }   __VARIANT_NAME_2;
              DECIMAL decVal;
              }   __VARIANT_NAME_1;
          } ;
      

      将其用作变量,就像脚本语言中的变量一样。

      【讨论】:

      • 我不知道这有什么帮助。
      【解决方案4】:

      如果你想要一个指向不同类型集合的指针,你应该使用结构体:

      struct T {
        char C;
        int I;
        ...
      }
      

      你会这样使用它:

      T* ptr = &T();
      ptr->C = "d";
      ptr->I = 1337;
      

      【讨论】:

      • 最后一节无法编译。
      猜你喜欢
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 2020-09-10
      • 2013-04-05
      • 1970-01-01
      相关资源
      最近更新 更多