0
// foo vector of unsigned chars
// contains 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xEC 0x82
std::vector< unsigned char > foo;
long some_long = (long)&foo[6];

// i want the unsigned chars 0x00, 0x1F, 0xEC 0x82 to
// make up the long decimal value of 2092162

Now the above would work if my system was big-endian however how do i get this to work for little-endian?

Also is the above way preferred? or should I be using something like below:

std::copy(&foo[6], &foo[6] + sizeof(long), reinterpret_cast<unsigned char*>(&some_long));
3
Contributors
5
Replies
6
Views
6 Years
Discussion Span
Last Post by Insensus
0

>>long some_long = (long)&foo[6];

I think that's called undefined behavior, typecasting an address into a long integer. The two may or may not be the same size, depending on the compiler you are using.

The way I would do it is like this: long some_long = *(long *)&foo[6];

-1

Is reversing the vector an option?
I guess this should work:

reverse(foo.begin(), foo.end());
long some_long = *(long *)&foo[0];
0

Won't help. If you are converting from big to little endien (or vice versa) you will just simply have to rewrite the order of the bytes. typecasting will not affect that.

0

just in case anyone was interested here is how I solved this.

// function to swap endianness
long int swap_long(long int i)
{
    unsigned char bit1, bit2, bit3, bit4;

    bit1 = i & 255;
    bit2 = ( i >> 8 ) & 255;
    bit3 = ( i >> 16 ) & 255;
    bit4 = ( i >> 24 ) & 255;

    return ((int)bit1 << 24) + ((int)bit2 << 16) + ((int)bit3 << 8) + bit4;
}

// function to read data from a vector at a given offset
long int _int32(const std::vector< unsigned char >& data, long offset, bool swap_endian)
{
    long int i = *(long int*)&data[offset];
    
    if (swap_endian)
        return swap_long(i);
    else
        return i;
}

int main()
{
    // assuming foo contains the following series of unsigned chars
    // 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xEC 0x82
    // i want the unsigned chars 0x00, 0x1F, 0xEC 0x82 to
    // make up the long decimal value of 2092162

    unsigned char bar[] = { 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xEC, 0x82 };
    std::vector< unsigned char >foo(bar, bar + sizeof(bar) / sizeof(unsigned char));

    long int myint = _int32(foo, 6, true);

    std::cout << "myint as dec: " << myint << std::endl;
    std::cout << "myint as hex: 0x" << std::hex << std::setw(8) << std::setfill('0') << myint << std::endl;

    return 0;
}
0

And just because I have it finished now anyway, here is what I just made. :P

template <typename T>
T switchEndian(unsigned char * from)
{
	T tmp = 0;
	for(unsigned idx = 0; idx < sizeof(T); idx++) {
		tmp += (from+(sizeof(T)-idx-1))[0] << idx*8;
	}
	return tmp;
}
long result = switchEndian<long>(&foo[6]);

It might be bad code though so I'm not very skilled.

Edited by Insensus: n/a

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.