C ++ htonll和返回

我找到了以下代码,它能够将int64_t转换为网络字节顺序。 现在我需要相反的代码,这样网络字节顺序就会转换回我的小端机器。 代码是这样的。

int64_t decode(void* value){ int64_t vv = *((int64_t*) value); int num = 42; if(*(char *)&num == 42) //test big/little endian return (((uint64)htonl(vv)) <> 32); else return vv; } 

非常感谢!

你的htonll的代码

 #define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl((x) >> 32)) 

端到端翻转字节。 如果将其应用两次,则会将值恢复为其原始状态。 所以相同的function可以用于ntohll

htonl可以通过以下步骤完成

  • 如果它的大端系统直接返回值。 无需进行任何转换。 如果是litte endian系统,需要做以下转换。
  • 取LSB 32位并应用’htonl’并移位32次。
  • 取MSB 32位(通过将uint64_t值右移32次)并应用’htonl’
  • 现在对第2步和第3步中收到的值应用位智能OR。

同样适用于ntohll

 #define HTONLL(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32))) #define NTOHLL(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32))) 

这是我如何使用联盟做到这一点。 比特移位方法也可以正常工作,但恕我直言,要做到这一点有点棘手。

 #include #include union MyUnion { int64_t i64; int32_t i32[2]; }; int64_t htonll(int64_t hostFormatInt64) { MyUnion u; u.i64 = hostFormatInt64; int32_t temp = u.i32[0]; u.i32[0] = htonl(u.i32[1]); u.i32[1] = htonl(temp); return u.i64; } int64_t ntohll(int64_t networkFormatInt64) { MyUnion u; u.i64 = networkFormatInt64; int32_t temp = u.i32[0]; u.i32[0] = ntohl(u.i32[1]); u.i32[1] = ntohl(temp); return u.i64; } void Test(int64_t i) { printf("Testing value %lli\n", i); int64_t networkI = htonll(i); printf(" Network format is %lli (0x%llx)\n", networkI, networkI); int64_t hostAgainI = ntohll(networkI); printf(" Back to host again %lli (0x%llx)\n", hostAgainI, hostAgainI); if (hostAgainI != i) { printf("ERROR, we didn't get the original value back!\n"); abort(); } } int main() { // A quick unit test to make sure I didn't mess anything up :) int64_t i = 0; while(1) { Test(i); Test(-i); i += rand(); } return 0; }