// 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));

Recommended Answers

All 5 Replies

>>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];

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

reverse(foo.begin(), foo.end());
long some_long = *(long *)&foo[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.

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;
}

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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.