Десериализуйте массив байтов к структуре

просто сгруппируйте свой результат с mnd столбец

SELECT t.mnd, SUM(t.pris)
FROM travel AS t
group by t.mnd
5
задан drby 6 February 2009 в 11:15
поделиться

6 ответов

Просто копирование, очень вероятно, повредится, по крайней мере, если данные могут прибыть из другой архитектуры (или даже просто компилятор), чем, что Вы идете. Это по причинам:

Та вторая ссылка GCC-конкретна, но это относится ко всем компиляторам.

Я рекомендую читать полевой байт байтом и собрать более крупное поле (ints, и т.д.) от тех байтов. Это дает Вам контроль порядка байтов и дополнение.

5
ответ дан 18 December 2019 в 13:19
поделиться

Некоторые процессоры требуют, чтобы определенные типы были правильно выровненные. Они не примут указанную упаковку и генерируют аппаратное сообщение.

И даже на упакованных структурах общего x86 может заставить код работать более медленно.

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

Между прочим, если Вы хотите простой и платформенно независимый механизм связи с привязкой ко многим языкам программирования, затем взглянули на YAMI.

5
ответ дан 18 December 2019 в 13:19
поделиться

#pragma pack(1) директива должна работать над большинством компиляторов, но можно проверить разработку, насколько большой структура данных должна быть (10 в случае, если моя математика корректна), и использование printf("%d", sizeof(Header)); проверять, что упаковка делается.

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

2
ответ дан 18 December 2019 в 13:19
поделиться

Скажите мне, если я неправ, но AFAIK, делая его, который тот путь гарантирует Вам, что данные корректны - принятие типов, имеют тот же размер на Ваших различных платформах:

#include <array>
#include <algorithm>

//#pragma pack(1) // not needed

struct Header
{
    unsigned short bodyLength;
    int msgID;
    unsigned short someOtherValue;
    unsigned short protocolVersion;
    float testFloat;

    Header() : bodyLength(42), msgID(34), someOtherValue(66), protocolVersion(69), testFloat( 3.14f ) {}
};

int main()
{
    std::tr1::array<char, 128> msgBuffer;
    Header header;

    const char* rawData = reinterpret_cast< const char* >( &header );

    std::copy( rawData, rawData + sizeof(Header), msgBuffer.data()); // assuming msgBuffer is always big enough

    system("PAUSE");    

    return 0;
}

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

1
ответ дан 18 December 2019 в 13:19
поделиться

Я категорически не согласен с идеей считать байт байтом. Если Вы заботитесь об упаковке структуры в объявлении структуры, можно скопировать в структуру без проблемы. Для проблемы порядка байтов, снова читая байт байтом решает проблему, но не дает Вам универсальное решение. Тот метод является очень хромым. Я сделал что-то вроде этого прежде для подобного задания, и оно работало хорошо без незначительного сбоя.

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

Например, определением структуры, которую Вы дали выше, являются "s i s s". (s = короткий, я = интервал) Затем я даю адрес структуры, это определение и опцию упаковки структуры этой структуры к специальной функции, которая имеет дело с вещью порядка байтов и вуаля она сделана.

SwitchEndianToBig (&header, "s i s s", 4);//4 = опция упаковки структуры

1
ответ дан 18 December 2019 в 13:19
поделиться

Я знаю, кем я общаюсь с, таким образом, я не должен действительно волноваться о порядке байтов. Но мне нравится избегать компилятора определенные команды так или иначе.

Таким образом как насчет этого:

const int kHeaderSizeInBytes = 6;

struct Header
{
    unsigned short bodyLength;
    unsigned short msgID;
    unsigned short protocolVersion; 

    unsigned short convertUnsignedShort(char inputArray[sizeof(unsigned short)])
        {return (((unsigned char) (inputArray[0])) << 8) + (unsigned char)(inputArray[1]);}

    void operator<<(char inputArray[kHeaderSizeInBytes])
    {
        bodyLength = convertUnsignedShort(inputArray);
        msgID = convertUnsignedShort(inputArray + sizeof(bodyLength));
        protocolVersion = convertUnsignedShort(inputArray + sizeof(bodyLength) + sizeof(msgID));
    }
};

int main()
{
    boost::array<char, 128> msgBuffer;
    Header header;

    for(int x = 0; x < kHeaderSizeInBytes; x++)
        msgBuffer[x] = x;

    header << msgBuffer.data();

    system("PAUSE");    

    return 0;
}

Избавляется от прагмы, но это не столь общего назначения, как я хотел бы. Каждый раз, когда Вы добавляете поле к заголовку, необходимо изменить <<функция. Можно ли выполнить итерации по полям структуры так или иначе, получить ли тип поля и вызвать ли соответствующую функцию?

0
ответ дан 18 December 2019 в 13:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: