我有一个struct
,它由多个32位元素组成。我应用了#pragma pack (4)
,因此以下结构是线性的并且是对齐的。
struct
{
int a; // 4 bytes
int b; // 4 bytes
int c; // 4 bytes
} mystruct; // total 16 bytes
如何交换这些元素(小 - >大端)?
方法是void swap(void* a, int b);
,其中a
指向结构,b
整数表示结构的大小。
例如:
void swap(void* a, int b)
{
//FIXME !
for (int i = 0; i < b; i+= 32)
{
a = (a & 0x0000FFFF) << 16 | (a & 0xFFFF0000) >> 16;
a = (a & 0x00FF00FF) << 8 | (a & 0xFF00FF00) >> 8;
a += 32;
}
}
答案 0 :(得分:4)
您可以在不使用临时字符的情况下交换两个字节:
void byteswap( unsigned char & a, unsigned char & b )
{
a ^= b;
b ^= a;
a ^= b;
}
现在让我们将它应用于可变长度的数字
template< typename T >
void endianSwap( T & t )
{
unsigned char * first = reinterpret_cast< unsigned char * >( &t );
unsigned char * last = first + sizeof(T) - 1;
while( first < last )
{
byteswap( *first, *last );
++first;
--last;
}
}
对于您的结构,您可以:
void endianSwap( mystruct & s )
{
endianSwap( s.a );
endianSwap( s.b );
endianSwap( s.c );
}
当然,作为使用byteswap的endianSwap的替代方法,我们可以使用std :: reverse。
template<typename T> endianSwap( T& t )
{
unsigned char * begin = reinterpret_cast<unsigned char *>(&t);
unsigned char * end = begin + sizeof( T );
std::reverse( begin, end );
}
答案 1 :(得分:1)
这是您日常工作的可能修复
void swap(void* a, int b)
{
for (int i = 0; i < b; i += 4)
{
int* p = (char*)a + i;
*p = (*p & 0x0000FFFF) << 16 | (*p & 0xFFFF0000) >> 16;
*p = (*p & 0x00FF00FF) << 8 | (*p & 0xFF00FF00) >> 8;
}
}
未经测试,但希望更接近正确。
答案 2 :(得分:0)
如果您使用的是基于* nix的计算机。有一些有用的功能可以做到:
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32); // from host to network
// means little to big if your machine is x86
答案 3 :(得分:0)
void swap(void* A, int b)
{
//FIXME !
int *c = (int*)A; // have to cast to an existing type. 'void' doesnt exist
for (int i = 0; i < b; i+=4) // we are flipping 4 bytes at a time
{
unsigned int a=*c; // read the content, not the address
// have to have unsigned, otherwise (a&0xff00ff00)>>8 extends the sign bit
a = (a & 0x0000FFFF) << 16 | (a & 0xFFFF0000) >> 16;
a = (a & 0x00FF00FF) << 8 | (a & 0xFF00FF00) >> 8;
*c++= a; // write back the content
}
}
无论如何:我喜欢用c或c语言进行字节交换的方法是通过副本: 这个概念比内置函数的名称更容易记住。
void swap(char *d, char *s, int N) { for (i=0;i<N;i++) d[i^3]=*s++;}
答案 4 :(得分:0)
我假设通过little-&gt; big endian你的意思是颠倒每个4字节元素中字节的顺序。我还假设通过“结构上的a
空指针”,你的意思是“结构上的a
指针”。
您的代码中存在一些错误。试试这个:
void swap(void* a, int b)
{
for (int *pInt = (int *)a; pInt < ((char *)a + b); pInt++)
{
*pInt = (*pInt & 0x0000FFFF) << 16 | (*pInt & 0xFFFF0000) >> 16;
*pInt = (*pInt & 0x00FF00FF) << 8 | (*pInt & 0xFF00FF00) >> 8;
}
}