Итак, у меня есть следующие функции:
void SomeClass::Read(__in uint32_t& Res)
{
ReadBinary<uint32_t>(Res);
}
template < typename T >
void SomeClass::ReadBinary(T& Res)
{
size_t sBytesToRead = sizeof(T);
Res = 0;
std::vector<char> vcBuffer(sBytesToRead);
m_Fstream.read(&vcBuffer[0], sBytesToRead);
// little endian
if (m_Endian == LITTLE_ENDIAN)
for (int n = sBytesToRead-1; n >= 0; n--)
Res = (Res << 8) + vcBuffer[n];
// big endian
else
for (unsigned n = 0; n < sBytesToRead; n++)
Res = (Res << 8) + vcBuffer[n];
}
void SomeClass::DetectEndian()
{
int num = 1;
if (*(char *)&num == 1)
m_Endian = LITTLE_ENDIAN;
else
m_Endian = BIG_ENDIAN;
}
Эти функции предназначены для обнаружения системного порядка и чтения двоичных чисел из файла.
по некоторым причинам я не получаю ожидаемые значения. Откуда мне знать? Я написал простой скрипт на Python:
mode = 'rb'
with open(filename, mode) as f:
print struct.unpack('i', f.read(4))[0]
print struct.unpack('i', f.read(4))[0]
Кажется, что когда целое число мало, чтобы содержаться в одном байте, значения обеих программ одинаковы. Однако, как только целое число состоит из нескольких байтов, я получаю разные значения.
это заставляет меня думать, что у меня проблема с этими строками:
// little endian
if (m_Endian == LITTLE_ENDIAN)
for (int n = sBytesToRead-1; n >= 0; n--)
Res = (Res << 8) + vcBuffer[n];
Есть идеи?
Если char
подписан в вашем компиляторе (и, скорее всего, так), тогда он может быть отрицательным, поэтому вы будете вычитать значение вместо его добавления, как продемонстрировано это демо.
использование unsigned char
или же uint8_t
вместо char
,