тип указателя для буфера, который содержит несколько разных типов

Если я хочу объявить указатель на буфер, а буфер содержит несколько разных типов (int, char и т. д.), то какой тип я должен сделать указателем на буфер? пустота *?


person user3800036    schedule 25.08.2014    source источник
comment
Как хранятся данные? двоичный? Вы когда-нибудь слышали о TLV?   -  person PaperBirdMaster    schedule 25.08.2014
comment
Я не думаю, что у нас достаточно информации, чтобы ответить. Как вы определяете тип содержимого, например, при использовании буфера? В любом случае, на первый взгляд кажется, что переосмысление дизайна может быть в порядке вещей.   -  person Angew is no longer proud of SO    schedule 25.08.2014
comment
Я добавляю содержимое в буфер с помощью программы под названием Game Maker Studio. Я использую функцию GML (Game Maker Language) с именем buffer_write для хранения данных. Я получаю адрес в буфер, используя buffer_get_address и передавая адрес в DLL, чтобы я мог получить доступ к буферу из DLL.   -  person user3800036    schedule 25.08.2014
comment
GM Studio использует только два типа: строковый и реальный. Я считаю, что они переводятся в char и double соответственно.   -  person user3800036    schedule 25.08.2014


Ответы (4)


Да void * - это универсальный указатель. Но использовать его следует с осторожностью. Если вы хотите использовать библиотеку, укажите тип any. библиотеки boost является безопасным универсальным контейнером

person webNeat    schedule 25.08.2014

Из вашего описания видно, что вы пытаетесь спроектировать собственную сериализацию различных типов в буфер (в реальной жизни сделать это переносимым способом сложно, и в большинстве случаев хорошо определенная библиотека сериализации, такая как буферы протокола решают проблему).

В прошлом, когда я использовал пользовательское управление буфером, я видел три способа, которыми люди управляют своими буферами.

  1. void* и тщательно управляйте смещениями в своем коде
  2. char* и использовать тот факт, что char* будет байтом.
  3. uint8_t* как переносимый способ чтения байта данных из буфера.

Помните, что если вы выделяете буфер для управления различными типами данных, вы в конечном итоге будете внимательно читать байты и приводить их к соответствующим типам. Мне нравится третий подход как чистый способ чтения байтов из буфера и сохранения выравнивания байтов в буфере в процессе.

person jayadev    schedule 25.08.2014

Под окнами вы можете использовать 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;
    } ;

Используйте его как переменную, как переменную в языке сценариев.

person ravin.wang    schedule 25.08.2014
comment
Я понятия не имею, как это помогает в любом случае. - person devdot; 25.08.2014

Если вам нужен один указатель на коллекцию разных типов, вы должны использовать структуру:

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

Вы бы использовали это так:

T* ptr = &T();
ptr->C = "d";
ptr->I = 1337;
person devdot    schedule 25.08.2014
comment
Этот последний раздел не будет компилироваться. - person 0x499602D2; 25.08.2014