Table of Contents

نوشتن کد قابل حمل C یک سنگ بنای مهندسی نرم افزار حرفه ای است که برنامه های کاربردی را قادر می سازد تا در معماری های مختلف سخت افزاری، سیستم عامل ها و کامپایلرهایی با حداقل کار مجدد اجرا شوند. Portability باعث کاهش هزینه نگهداری، گسترش پایگاه کاربر و کد های آینده در برابر سیستم عامل های در حال تحول می شود.این مقاله بهترین شیوه های مبارزه برای دستیابی به پورتینگ واقعی، بر اساس C و استاندارد تجربه واقعی در جهان را مختل می کند.

درک تفاوت های پلتفرم

قبل از استفاده از تکنیک های پورتینگ، توسعه دهندگان باید انواع تغییراتی را که بین پلتفرم ها وجود دارد، تشخیص دهند: این تفاوت ها شامل چهار دسته گسترده است: رفتار کامپایلر، API های سیستم عامل، معماری سخت افزار و محدودیت های منابع.

تغییرات اجباری

کامپایلرهای C – از GCC، Clang و MSVC تا ابزارهای جاسازی شده مانند IAR و Keil – پیاده سازی استاندارد C با سطوح مختلف انطباق.آنها ممکن است در مدیریت خود از امضاness، طرح های کوچک، ساختار، و معانی دقیق از یا [F:2] پسوندهای زبان پنهان (F:3g) نیز می تواند وابستگی های پنهان را ایجاد کند.

تفاوت های سیستم عامل

سیستم های مشابه (لینوکس، macOS، BSD) بسیاری از API ها را به اشتراک می گذارند، اما ویندوز مجموعه ای از سیستم های اساسا متفاوت را در معرض قرار می دهد. File I/O، Threading، Dynamic link، سیگنال ها و کنترل فرآیند اغلب نیاز به جمع آوری مشروط یا یک لایه انتزاعی دارند.حتی حساسیت پرونده و جداکننده های مسیر (backslash در مقابل اسلیم) نیاز به مراقبت دارند.

معماری سخت افزار و پایان

پردازنده ها در اندازه کلمه (۳۲ بیتی در مقابل ۶۴ بیتی)، سفارش بایت (bigendian یا little-endian)، الزامات تراز و ویژگی های دستورالعمل تنظیم شده متفاوت هستند که فرض می کنند (FLT:4) ۳۲ بیت است یا یک اشاره گر متناسب با یک در بسیاری از سیستم عامل های Endianness زمانی که برای ذخیره سازی داده ها یا انتقال فایل های شبکه ضروری می شود.

منابع Constraints

سیستم های جاسازی شده یا اهداف عمیقا جاسازی شده ممکن است فاقد سیستم عامل باشند، اندازه های پشته / Heap محدود داشته باشند و پیاده سازی با کد های فرمت محدود باید از فرضیات در مورد دسترسی به حافظه و پشتیبانی زمان اجرا اجتناب کنند.

بهترین روش های Core Best Practices for Portable C Code

Rely on Standard C Library

کتابخانه استاندارد C (ISO/IEC 9899) پایه ای را فراهم می کند که هر کامپایلر مطابق باید تابع هایی مانند (FLT-7) را عرضه کند، و به طور یکسان در سراسر سیستم عامل ها عمل می کند.

استفاده از انواع Integer ثابت

[در این میان] [در این میان]، [[[[[ویرایش]]] [[[[۳]]] [[۳]]] [[۳]]] [[۳]]] [[۳]]] [[۳]]] [[۳]]]] [FLT: [۳] همیشه از آنها استفاده کنید، به عنوان مثال، هنگامی که با استفاده از [FLT] این انواع چاپ، به طور مشابه استفاده می کنند.

#include <stdint.h>
#include <inttypes.h>
int32_t val = -100;
printf("Value: %" PRId32 "\n", val);

اجتناب از مفروضات در مورد انواع بنیادی

و هرگز گمان نکنید که [در برابر این آیات] 32 بیت است، یا 64 بیت (مشرکان) یا برای استخراج اموال در زمان کامپایل شده است.

پایان دادن به درخواست

هنگامی که تبادل داده های باینری در سراسر دستگاه (شبکه، فایل یا حافظه مشترک)، همیشه به یک سفارش شناخته شده تبدیل می شود - به طور معمول شبکه بایت (big-endian) توابع POSIX (FLT 31)، ، ، [FLT33، به طور گسترده ای در دسترس هستند؛ برای سیستم های غیرPOSIX، پیاده سازی خود را ارائه می دهد و استفاده از زمان ردیابی.

سیستم عملیات فایل های Abstract File System Operations

فایل مسیر de Limiters متفاوت است ([FLT36] در یونیکس، در ویندوز، از ماکروها یا یک تابع کوچک سودمند که مسیر را عادی می کند، برای دایرکتوری آن، POSIX [FLT 38 API استاندارد است؛ در ویندوز شما می توانید [FLT 39] پشت همان رابط را ببندید.

مینیمال کردن رفتار تعریف نشده و اجرایی شده

این استاندارد، بسیاری از عملیات را به عنوان تعریف نشده یا پیاده سازی تعریف شده، شامل امضای سر صحیح، تغییر بیش از عرض نوع، و ارزیابی تجزیه و تحلیل گران استاتیک مانند Cppcheck [FLT 1] و یا C-Tidy [FLT3] استفاده از الگوهای استاتیک مانند نوشتن و کد به شدت مطابقت دارد.

استفاده از Preprocessor macros برای انتخاب زمان Compile-Time

در این میان، استفاده از این طرح برای استفاده از آن ضروری است؛ اما در این صورت، استفاده از آن از آن به صورت کامل و مناسب است.

#ifdef _WIN32
 #include <windows.h>
 #define SLEEP(ms) Sleep(ms)
#else
 #include <unistd.h>
 #define SLEEP(ms) usleep((ms)*1000)
#endif

استفاده از لایه های انتزاع برای فراخوان های سیستم

برای جمع آوری، سوکت ها، تایمر ها و مدیریت حافظه، یک بسته بندی نازک ایجاد کنید (برای مثال، نوع 48 را تعریف کنید و تابع FLT 49 را که نقشه هایی برای موضوعات مثبت در یونیکس و در ویندوز دارد، همان رویکرد برای کتابخانه های پویا ([F51] در مقابل [FLT] فراهم می کند.

تست روی پلتفرم های متعدد در اوایل و اغلب

خط لوله های ادغام مستمر (CI) باید مجموعه تست را در لینوکس، macOS، ویندوز و هر هدف جاسازی شده کامپایل و اجرا کنند.استفاده از cross-compilers و emulator (به عنوان مثال QEMU) برای گرفتن اشکالات معماری خاص قبل از استقرار به اجرای خودکار با ابزار مانند ctest یا [F:2/2]

تکنیک های پیشرفته پورتینگ

ساخت سیستم پیکربندی با CMake یا Autotools

سیستم های ساخت مدرن می توانند ویژگی های پلتفرم را در زمان پیکربندی تشخیص دهند. ، و ماژول ها یک [FLT 56] را تولید می کنند که کد شما می تواند جایگزین آن شود.

// Generated config.h
#define HAVE_STDINT_H 1
#define WORDS_BIGENDIAN 0
#define SIZEOF_LONG 8

دانلود زیرنویس فارسی فیلم Intrinsics

هنگامی که عملکرد نیاز به دستورالعمل های خاص پلت فرم (به عنوان مثال، سیم D، CPUID)، آنها را در فایل های جداگانه قرار دهید و فایل مناسب را در طول ساخت انتخاب کنید.استفاده از اجزای داخلی کامپایلر (مانند از GCC / Clang / Clang / IClang / US) به جای inline، زیرا ذاتی در سراسر کامپایلرها در همان معماری قابل حمل هستند.

ساختارهای داده های Align به صورت ناخواسته

استفاده از ساختار و ترازبندی متفاوت است. [۶۰] و از C11 ( برای اجرای ترازنامه های قدیمی تر، از پیش پردازنده های کار بر اساس پیش پردازنده ( برای GCC، برای MSVC] استفاده کنید.

قابلیت مدیریت سیگنال

سیگنال ثابت ( و کنترل سیگنال ایمن به طور گسترده ای متفاوت است. [FIX] API ترجیح می دهد به قدیمی تر در ویندوز، سیگنال ها از طریق کنترل کننده های کنسول شبیه سازی شده اند.

سقوط های جهانی واقعی و چگونگی جلوگیری از آن

در این باره می توان گفت: «نقوا» (وَهُمْهُمْهُمْهُمْهُمْهُمْهُمْهُمِهُمْهُمِهُمْهُوا مِنْهُمِهُمِهُمِهُوا مِهُمِهُمِهُوا مِهُمِهُمِنْهُوا مِنِهُوا مِهُوا مِهُوا مِنِنِنِنِنِنِنِنْهُمِنِنْهُوا مِنِنِنِنِنِنِنْهُوا مِنْهُوا مِنَهُوا مِنِنْمِنْهُمِنْمِنِنِنِنِنِنِنَهُمِنِنِنِنِنِنِنِنِنِنِنِنِنِنِنِنِ

استاندارد در POSIX اما از دست رفته در بسیاری از سیستم عامل های جاسازی شده و محیط های ویندوز قدیمی استفاده از یک پیاده سازی قابل حمل مانند plibc یا یک بسته حداقل تحت مجوز هر گونه.

در این میان، [[رده:رده:]]، [[رده:رده:رده:رده:رده:

استاندارد C فقط می گوید یک نوع واقعی است که قادر به نمایندگی از زمان است.در برخی از سیستم های جاسازی شده آن را یک ارزش 32 بیتی امضا نیست؛ در دیگران آن را یک عدد صحیح 64 بیتی امضا شده است که هرگز محاسبه در بدون چک کردن خواص آن، و یا استفاده از برای تفاوت ها.

غفلت از Thread-Safety در Calls سیستم

در این میان، [[مسلمان]] و |S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|

نتیجه گیری

نوشتن کد قابل حمل C هر دو یک نظم و یک سرمایه گذاری است که با نزدیک شدن به استاندارد C، انتخاب انواع پهنای باند ثابت، رابط های سیستم انتزاعی و تست در سیستم عامل های مختلف، توسعه دهندگان می توانند نرم افزار را تولید کنند که به طور قابل اعتماد در محیط هایی از ابرکامپیوتر به میکروکنترلرها اجرا می شود؛ شیوه های ذکر شده در اینجا - همراه با سیستم ساخت مدرن و تجزیه و تحلیل استاتیک - یک پایه پایدار برای توسعه چرخه عمر متقاطع است که در سراسر یک هدف تقسیم بندی تقسیم می کند؛