تحقق من نوع وحدة المعالجة المركزية في وقت التشغيل لبرنامج C على Mac

StackOverflow https://stackoverflow.com/questions/1834373

سؤال

كيف يحدد برنامج C، في وقت التشغيل (لا يتكرر الوقت)، سواء كان يعمل على وحدة المعالجة المركزية الصغيرة الناعمة أو الهندية الكبيرة؟

السبب في أنه يجب أن يكون "وقت التشغيل"، وليس "وقت متوافق"، لأنني أقوم ببناء البرنامج بالتنسيق الثنائي العالمي في Mac OSX، باستخدام Mac Mac مع Intel-CPU. ومن المتوقع أن يعمل هذا البرنامج على كل من وحدة المعالجة المركزية Intel و Power-PC. أي، من خلال التنسيق الثنائي العالمي على Mac، أريد بناء برنامج باستخدام Intel-CPU وتشغيله ضمن وحدة المعالجة المركزية PPC.

يعد المنطق في برنامجي الذي يحتاج إلى فحص وحدة المعالجة المركزية هو وظيفة تغيير الطلب على طلبات المضيف إلى الشبكة للأعداد الصحيحة 64 بت. الآن لدي مبادلة عمياء أوامر البايت، والذي يعمل موافق على Intel-CPU، ولكن يكسر في PPC. ها هي وظيفة C:

unsigned long long
hton64b (const unsigned long long h64bits) {
   // Low-order 32 bits in front, followed by high-order 32 bits.
   return (
       (
        (unsigned long long)
        ( htonl((unsigned long) (h64bits & 0xFFFFFFFF)) )
       ) << 32
      )
      |
      (
       htonl((unsigned long) (((h64bits) >> 32) & 0xFFFFFFFF))
      );
}; // hton64b()

أي طريقة أفضل للقيام بذلك بطريقة عبر المنصة؟

شكرا

هل كانت مفيدة؟

المحلول

  • سيكون هناك وحدات ماو ما قبل المواسعة المتاحة لاختبار Wether It Endian كبيرة / صغيرة. على سبيل المثال
 #ifdef Little_endian تفعل ذلك الطريق الإنادي القليل # هل تفعل ذلك الطريق الإناث الكبيرة #endif.

هذا هو تجميع الوقت، لكن مصدر ثنائيات الدهون يحصل على ترجمة منفصلة لكل بنية، هذه ليست مشكلة.

  • لست متأكدا مما إذا كان لدى Macosx وظيفة Betoh64 () في SYS / ENDIAN.H - إذا كان الأمر كذلك - استخدم ذلك سيفعل الشيء الصحيح.
  • النهج الأخير هو ببساطة القيام بتفريغ البايت الفردية بطريقة غير معقولة إلى Endian المضيف - تحتاج فقط إلى معرفة النظام الذي توجد به البايت من المصدر.

    uint64_t unpack64(uint8_t *src)
    {
       uint64_t val;
    
       val  = (uint64_t)src[0] << 56;
       val |= (uint64_t)src[1] << 48;
       val |= (uint64_t)src[2] << 40;
       val |= (uint64_t)src[3] << 32;
       val |= (uint64_t)src[4] << 24;
       val |= (uint64_t)src[5] << 16;
       val |= (uint64_t)src[6] <<  8;
       val |= (uint64_t)src[7]      ;
    
       return val;
    }
    

نصائح أخرى

لا تهتم الفحص؛ ما عليك سوى استخدام Hton * أينما كنت بحاجة إلى قيمة مستقلة للشبكة. مع تصميم جيد، يجب أن يقتصر ذلك على الوحدة النمطية التي تتضمن واجهاتها بين برنامجك وأي شيء يحتاج إلى أعداد صحيحة مستقلة للشبكة.

على أنظمة Big-Endian التي هي بالفعل في ترتيب الشبكة، ربما تكون Hton * ماكرو فقط، فهذا مجاني. على أنظمة Little-Endian، ستحتاج إلى القيام بذلك على أي حال، لذلك تحقق مما إذا كنت بحاجة إلى القيام بذلك، فسيطرحك فقط

إذا لم يكن هذا غير كاف، فستحتاج إلى تقديم تفسير أفضل لما تحاول إنجازه ولماذا تحتاج إلى معرفة نخلة النظام في وقت التشغيل.

هل تدرك أن الثنائيات العالمية على ماك تترك عدة مرات، مرة واحدة لكل بنية؟ أتصور أنه عندما تتحدث عن تجميع الوقت، فأنت تشير إلى استخدام نظام تكوين / جعل الخاص بك لإعلام المصدر .... ما عليك سوى استخدام ثوابت دول مجلس التعاون الخليجي (مثل Little_endian)

لا تحتاج إلى التحقق من الانتصفية في وقت التشغيل. عند ترجمة تطبيق كثنائي عالمي، يتم تجميع عدة مرات مع تحديد وحدات الماكرو المناسبة، حتى لو كنت تقوم ببناء على آلة إنتل. في وقت التشغيل، سيقوم Loader Mach-O باختيار أفضل بنية للتشغيل من ثنائي عالمي (أي PPC على PowerPC أو I386 على Intel).

ثنائي عالمي لا يعني ثنائي واحد للحصول على بنية متعددة. وهذا يعني ثنائي سمين واحد يحتوي على ثنائي واحد للحصول على بنية واحدة.

يرجى الرجوع إلى http://developer.apple.com/legacy/mac/library/documentation/macosx/conectual/universal_binary/universal_binary_intro/universal_binary_intro.html. لمزيد من التفاصيل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top