Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mencapai Kemudahalihan Apabila Menukar Integer 64-Bit kepada Susunan Bait Rangkaian dalam C ?

Bagaimana untuk Mencapai Kemudahalihan Apabila Menukar Integer 64-Bit kepada Susunan Bait Rangkaian dalam C ?

Susan Sarandon
Susan Sarandonasal
2024-10-30 04:37:28813semak imbas

How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C  ?

Kebimbangan Mudah Alih untuk Penukaran Tertib Bait Rangkaian Integer 64-Bit dalam C

Dalam C , timbul keperluan untuk menukar integer 64-bit kepada "perintah bait rangkaian" untuk aplikasi tertentu, seperti melaksanakan protokol memcache. Walaupun wujud fungsi htonl() untuk menukar integer 32-bit, fungsi yang serupa untuk integer 64-bit (htonll()) masih sukar difahami.

Pertimbangan Fungsi Standard

Malangnya, pada masa ini tiada fungsi standard mudah alih dalam C yang boleh melakukan penukaran pesanan bait rangkaian 64-bit. Ketiadaan ini mewujudkan keperluan untuk pelaksanaan tersuai.

Pelaksanaan Tersuai

Untuk melaksanakan htonll(), kita mesti terlebih dahulu menentukan endian sistem. Satu kaedah yang boleh dipercayai ialah menilai nilai pembolehubah integer dengan susunan bait yang diketahui (mis., 42) pada masa jalan:

<code class="cpp">static const int num = 42;
bool isBigEndian = (*reinterpret_cast<const char *>(&num) == num);</code>

Seterusnya, kita boleh melakukan penukaran mengikut endian:

<code class="cpp">uint64_t htonll(uint64_t value)
{
    if (isBigEndian)
    {
        const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
        const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));

        return (static_cast<uint64_t>(low_part) << 32) | high_part;
    }
    else
    {
        return value;
    }
}

Macros for Portability

Sebagai alternatif, makro boleh menyediakan cara ringkas untuk mentakrifkan htonll() dan rakan sejawatannya, ntohll():

<code class="cpp">#define htonll(x) ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))</code>

Ini makro bergantung pada gelagat pesanan bait intrinsik sistem untuk menentukan pertukaran bait yang diperlukan.

Makro Khusus Pengkompil

Sesetengah penyusun dan sistem pengendalian menyediakan makro khusus untuk menentukan endianness . Sebagai contoh, pada sistem yang menyokongnya, kita boleh menggunakan:

<code class="cpp">#if __BIG_ENDIAN__
# define htonll(x) (x)
# define ntohll(x) (x)
#else
# define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
#endif</code>

Dengan menggunakan teknik ini, pelaksanaan tersuai bagi htonll() dan ntohll() boleh dibuat mudah alih merentas pelbagai sistem dan penyusun.

Atas ialah kandungan terperinci Bagaimana untuk Mencapai Kemudahalihan Apabila Menukar Integer 64-Bit kepada Susunan Bait Rangkaian dalam C ?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn