اینم یه تجربه پراکنده دیگه!

نوشتن این روزها سخت شده ولی من باز سعی میکنم که یه حضور کمرنگی در صحنه داشته باشم. این دفعه میخواستم در مورد یه موضوع جالب مرتبط با متغیر در سی بنویسیم

مشکل با متغیر محلی بزرگ

ما یه کد سی داشتیم که یه متغیر local با حجم حدودا ۱۰ کیلو بایت تعریف شده بود و مقدار دهی اولیه شده بود(عکس بود). همیشه کامپایلر به این قسمت از کد که میرسید کلی طول میکشید تا بتونه کد رو کامپایل کنه و همیشه اعصاب ما رو خورد میکرد. تا اینکه یه روز تصمیم گرفتیم مشکل رو حل کنیم. راه حل‌هایی که پیش رومون بود اینها:

  1. متغیر رو کلا حذف کنیم. که خب نمیخواستیم صورت مساله رو حذف کنیم
  2. متغیر رو global میکردیم که خب همه میتونستن تغییرش بدن و برامون بد بود
  3. متغیر رو static کنیم. این تفاوتی برای ما نداشت فقط میخواستیم امتحان کنیم.

خب اول راه دوم رو امتحان کردیم. اتفاقا هم زمان کامپایل کم شد و هم حجم باینری تولید شده. وقتی راه سوم رو هم امتحان کردیم دیدیم که نتیجه با راه دوم یکیه و حجم باینری کم شده و این خوب بود. چون راه دوم ویژگی‌های متغیر local رو داشت و عیب در دسترس بودن برای همه رو هم نداشت.

بررسی چرایی راه‌حل

سوالی که برای ما پیش اومد این بود که چرا یه تغییر اینجوری اینهمه هم توی سرعت هم حجم باینری موثره؟ برای جواب دادن به این ماجرا یکم رفتم تحقیق کردم:

  • همه باینری‌ها از بخش‌های مختلفی تشکلی شدن که اگه assembly یادتون باشه شامل اینهاست
  • متوجه شدم که متغیرهای global توی data segment تعریف میشن و متغیرهای local توی stack segment تعریف میشن.
  • متوجه شدم که متغیرهای static هم توی data segment تعریف میشن.

پس هرچی بود زیر سر data segment بود از اینجا به بعدش بازی شد حدس و گمان در مورد چرایی دوتا اتفاق:
– چرا سرعت کامپیال بیشتر؟ احتمالا به این دلیل که کامپایلر با data segment راحت‌تر کار میکنه تا stack segment. اما این حدس حجم باینری کمتر رو توجیه نمیکنه چون در این دوحالت حجم متغیر ثابت مونده
– چرا حجم باینری کمتر؟ برای اینکار یکم باید یادمون بیاد توی assembly که چطور یه متغیر local تعریف میشه منظورم هست. یه متغیر local عملا اینه که اول یه مقداری توی stack قرار میگیره و در یه مرحله دیگه اون مقدار از stack خارج میشه. که این هم نیاز به کد سمت code segment داره هم نیاز به حافظه سمت stack segment داره.

خب با این حالت ما به حدس دقیق تری از اتفاق پشت پرده رسیدیم. اونم اینه که وقتی متغیر توی data segment قرار میگیره یه بخش توسط کامپایلر تخصیص داده میشه و مقادیر هم توی اون خونه‌ها نوشته میشه. ولی وقتی قرار باشه اون متغیر توی stack segment قرار بگیره هم کد تولید میشه هم حافظه تخصیص داده میشه که منجر به طولانی تر شدن کل روند میشه.

امیدوارم به دردتون خورده باشه
همین!

اینم یه تجربه پراکنده دیگه!

چند شب پیش یکی از دوستان با این سوال به سراغ من اومد:

مشکل اینه که وقتی با malloc یا new یک حافظه تخصیص میدی و با free یا delete حافظه رو برمیگیردونی, اون حافظه شاید بلاک هاش خالی بشه اما توی تسک لیست خالی به عنوان منابع استفاده شده میاره و تا پایان پروسه پاک نمیشه. از دوستانی که آشنایی دارن پیگیری کن ببین جریان چیه. مهمه .

خدا خیرت بده. یه جایی از حافظه نمایی رشد میکه و وقتی خالیش میکنیم (با اینکه از لیست heap سیستم عامل خالی میشه) اما توی لیست پروسه‌ها(مثل نتیجه ps) هنوز به عنوان حافظه استفاده شده هست و حافظه آزاد نمیشه !!!‌ عجیبه . کلی توی اینترنت اینو سوال کردن !!

من که لینوکسم. اما فکر کنم ویندوزم همینه. چون سوالای اینترنت هردوشونه

کلا بخوام سوال رو خلاصه کنم اینجوریه که چرا وقتی حافظه رو به سیستم‌عامل پس میدیم واقعا پس داده نمیشه. من یکم از دانسته‌هام استفاده کردم و یکم هم تحقیقات کردم

پیش‌نیازها

پیش نیازهایی که به نظرم باید بدونیم ایناست:

  • نکته صفر اینکه با توجه به تحقیقات من زیر کلمه کلیدی new از همون malloc استفاده میشه. پس بررسی malloc به تنهایی میتونه جوابی برای ما فراهم کنه.
  • اول اینکه باید بدونیم که وقتی malloc صدا زده میشه چه اتفاقی میفته. کاری که malloc میکنه اینه که heap پروسه رو بهت اختصاص میده. حالا heap توسط سیستم عامل مدیریت میشه و در صورت نیاز به پروسه‌ی شما حافظه بیشتری تخصیص میده.
  • دوم اینکه فضای heap توسط کرنل مدیریت میشه و به اصطلاح نگاشته میشه به یه چیزی به نام Virtual Memory
  • سوم اینکهVirtual Memory نگاشته میشن به چیزی به نام Memory Page که نزدیک به سخت افزار تره
  • چهارم اینکه Memory Page نگاشته میشن بلوک‌های واقعی حافظه. از این مطمئن نیستم اما این نزدکترین لایه به سخت افزاره که من باهاش آشنا هستم.

بررسی مساله

حالا اگه بخوایم مساله رو بررسی کنیم باید به چند‌تا سوال جواب بدیم:

  • اول اینکه malloc چطور عمل میکنه؟ در پیاده‌سازیش ساز و کارش چیه؟
  • دوم اینکه روند افزایش طول Virtual Memory و اضافه شدن Memory Pageها چطوره؟
  • سوم اینکه بعد از پس دادن Memory Pageها سیستم عامل چطور اونها رو از یک پروسه پس میگیره؟

خب جواب سوالا به ترتیب اینا به نظر میرسن:

  • پیاده‌سازی‌های متفاوتی از malloc وجود داره
    • پیاده‌سازی معمولا اون اینطوریه که پس از گرفتن حافظه وقتی free شد معمولا اونها رو به سیستم عامل پس نمیده و نگه میداره که شاید بعدا بخواد دوباره تخصیص بده.
    • دوم اینکه درخواست یک Memory Page جدید توسط دستوراتی مثل mmap و sbrk درخواست یک بلاک بزرگ حافظه میکنه و اون رو بنا به درخواست نرم‌افزار تخصیص میده.
    • بعدش هم اینکه برای اینکه یک Memory Page رو برگردونه به سیستم عامل بایستی تمام حافظه‌هایی که روی اون تخصیص داده شدن برگشت داده بشه. که این هم همیشه اتفاق نمی‌افته.
    • معمولا هم پیاده‌سازی‌ها اینجورین که حافظه‌ای که توسط sbrk افزایش پیدا کرده رو دست نمیزنن(دلیل دقیقش رو نمیدونم) و حافظه‌ای که توسط mmap اضافه شده رو به راحتی برمیگردونن.
  • تقریبا جواب سوال دوم رو هم تا الان دادم. مقدار Virtual Memory توسط glibc کنترل میشه و بوسیله malloc تخصیص داده میشه.
  • جواب سوال سوم هم اینه که کرنل لینوکس همیشه حافظه برگشت داده شده رو برنمیگردونه چون که هزینه داره فقط اون رو علامت میزنه که در صورت نیاز اون رو حذف کنه یا به swap ببره.

راه حل مساله

حالا بریم سراغ مساله اصلی(چرا حافظه برگشت داده شده برگشت نخورده) و توجیهی که براش پیدا کردیم:
* مهمترین دلیل این اتفاق به نظرم malloc هست که حافظه رو نگه داشته و برنگردونده
* دومین دلیلش هم میتونه این باشه که کرنل هنوز Memory Page رو برنداشته و فقط علامت زده

حالا راه حل چیه:
* اول اینکه به کرنل و glibc اعتماد کنیم
* دوم اینکه بیایم و این پارامتر مروبط به malloc رو تنظیم کنیم۴
* سوم اینکه بیایم از یه پیاده‌سازی دیگه برای تخصیص حافظه و آزاد سازی اون استفاده کنیم
* چهارم اینکه بیایم خودمون مستقم از mmap و munmap استفاده کنیم

امیدوارم اینا راه گشای دیگران هم باشه

برای مطالعه بیشتر:

۱

۲

۳

۴

همین!

اینم یه تجربه پراکنده دیگه!

من قبلا هم در مورد ابزارهایی مثل makefile و cmake که کامپیال کردن نرم‌افزارها بالاخص در زبان‌های C/C++ رو راحت می‌کنن نوشتم. البته باید بگم که هیچوقت بصورت کامل و درستی یاد نگرفتم که makefile چطوره و چطور میشه باهاش سرو کله زد تا اینکه در یکی از پروژه‌ها مجبور به استفاده از makefile شدم و با کمک یکی از دوستان یه پروژه متن‌باز پیدا کرد که یه مدل آماده makefile که توش تقریبا همه کارهای معمول انجام شده بود رو آورده بود.

توی این پست سعی درام که این پروژه متن‌باز رو معرفی کنم. خب اول باید بگم که شما برای هر پروژه جدید نیاز دارید که چندتا چیز رو مشخص کنید

  1. اینکه بدونید سورس پروژه کجاست.
  2. اینکه فولدرهایی که header ها توش قرار گرفته کجاست
  3. اینکه بدونید برنامه‌تون به چه کتابخانه‌هایی نیاز داره
  4. اینکه بدونید برنامه‌تون برای کامپیال شدن به کمک GCC به چه flagهایی نیاز داره.

بعد از اینکه این موارد رو دونستید و اونها رو پیدا کردید باید برید و بخشها مرتبط با این موارد رو توی makefile تغییر بدید به عنوان Customizable Section مشخص شده.

خب هر یک از این بخش‌های قابل تغییر برای خودش معنایی داره

  1. بخش MY_CFLAGS مقدار flag هایی هست که برای کامپیال کردن فایلها با پسوند c به کار میره. لازه به ذکره که بدونید flagهای C با C++ می‌تونن تفاوت اساسی داشته باشند
  2. بخش MY_LIBS نشون‌دهنده flag هایی هست که در فاز link قرار به linker داده بشه و با استفاده از اون کتابخانه ها شناسونده بشن. یه مثال برای این مقدار -lpthread هست که میگه کتابخانه pthread مورد نیاز این نرم‌افزار هست
  3. بخش CPPFLAGS بخشی هست که نشون میده flagهای کامپایل c++ چیا هستن. مثلا -std=gnu++11 که نشون میده میخوایم از استاندارد C++ 2011 استفاده کنیم. فولدر headerها رو هم توی این بخش اضافه می‌کنیم
  4. اگه به هر دلیل بخوایم flagهای دیگه ای به linker بدیم از LDFLAGS استفاده می‌کنیم.
  5. سورس نرم‌افزار رو با SRCDIRS جاهایی که سورس قرار گرفته رو نشون میده.
  6. و در نهایت PROGRAM نام نرم‌افزار رو نشون میده.

امیدوارم با این توضیحات کوتاه دستتون اومده باشه که چه کاری رو به چه صورت باید انجام بدید و در صورت هرگونه سوالی کامنت بگذارید و یادتون نره که من هنوز makefile رو بخوبی بلد نیستم! 😉

اینم یه تجربه پراکنده دیگه!

اول از همه بگم که این پست ۱۰۰ امین پست وبلاگ من هست که در نزدیک به سه سال منتشر شده! اولایی که تصیمم به نوشتن گرفتم فکر نمی‌کردم اینقدر بتونم دوام بیارم که ۱۰۰ تا پست بنویسم اما به نظر میرسه نوشتم! پس خوشحالم!

بریم سراغ پست ایندفعه. خب موضوعی که برای من همیشه مطرح بوده و باز هم مطرح هست اینه که شما چطور می‌تونید در زمان اجرا در زبان C یک کتابخانه‌ای که قبلا حتی از وجودش خبر نداشتید رو اجرا کنید. یه چیزی تو مایه‌های اینکه چطور می‌تونید یه پلاگین داشته باشید که بصورت پویا اجرا بشه. در زبان‌های سطح بالاتر این کار با آسونی بیشتری انجام میشه و حتی زبان برای شما امکاناتی رو فراهم کرده که به راحتی این کار رو می‌تونید انجام بدید. اما در C این عملیات خیلی سطح پایین بوده و بوسیله یه سری توابع خاص انجام میشه. لازم به ذکر میدونم که بگم که این کدها همشون توی محیط لینوکس و بهتره بگم مبتنی بر استاندارد POSIX قابل استناد هستن و در ویندوز احتمالا روند متفاوت خواهد بود.

شما با دوتا مساله روبرو هستید.
– اول اینکه یه فایل رو باز کنید و با اون به عنوان فایل اجرایی برخورد کنید! یعنی بصورت دقیقتر بگم که با محتوای اون کد به شکل Code Segment برخورد کنید.
– دوم اینکه بتونید حالا که فایل رو باز کردید بتونید توابع درون اون فایل رو به صورتی تشخیص بدید و صدا بزنید!

برای این کار کتابخانه استاندارد C توابعی را در فایل هدر dlfcn.h قرار داده است. روند کار نیز بدین صورت است که ابتدا فایل کتابخانه را باز کرده و سپس با اسم تابع فایل را جستجو کرده و اشاره‌گری به آدرس آن تابع باز می‌گرداند. از این پس با استفاده از این اشاره گر به تابع می‌توان آنرا اجرا نمود. کد نمونه این عملیات نیز به شکل زیر است.

همین!

برای مطالعهی بیشتر

QR Code

اینم یه تجربه پراکنده دیگه!

همه ما با مفهوم QR Code کم و بیش آشنا هستیم. یک نوع بارکد دو بعدی هست که درون خودش اطلاعاتی رو مخفی می‌کنه. استانداردهای متفاوتی هم داره. نسخه‌های متفاوتی هم داره. همچنین افزونگی اطلاعات هم توش در نظر گرفته شده که میشه در صورت خراب شدن QR Code اون رو تا حدی پوشش داد.

بعد از این مقدمه کوتاه باید بگم که توی یکی از کارهایی که من انجام میدادم نیاز داشتم که یک کتابخانه بیاد و برام متن‌هایی رو که از سمت سرور برای من ارسال میشه رو تبدیل به QR Code و اونها یا چاپ کنه یا نمایش بده! بعد از یه جستجوی ساده پیدا کردم که کتابخانه‌ای وجود داره به اسم libqrencode که این کار رو انجام میده. تنها کافیه که کد رو کامپایل کنید و اون رو در کنار برنامتون قرار بدید. و تقریبا هر چیزی رو تبدیل به QR Code کنید!

همچنین باید بگم که این کد رو میشه توی زبان‌های دیگه هم مورد استفاده قرار داد.

راه اندازی QR Code در فدورا و یک نمونه کد ساده

تنهای کاری که توی فدورا باید بکنید اینه که

رو نصب کنید.
نمونه کد استفاده از این کتابخانه هم ساده است:

همین!
پ.ن: نتیجه کار هم در عکس این پست قابل مشاهده است.

cmake diagram

اینم یه تجربه پراکنده دیگه!

متاسفانه یه مدت میشه که سرم بیش از اندازه شلوغ شده و نرسیدم خوب وبلاگ بنویسم. اما این هفته یه کار خوبی انجام دادم که گفتم اینجا مستندش کنم.

خب همونطور که ممکنه بدونید من توسعه اصلی کارهام در زبان‌های c و c++ هست. یکی از ویژگی‌هایی که این زبان‌ها دارن این هست که شما بایستی برای کامپایل شدن برنامه همیشه از یک IDE استفاده کنی یا از ابزارهایی مثل make برای لینوکس یا مثلا nmake در ویندوز. خب وقتی شما بخوای یه کد رو بین پلتفروم‌های مختلف و برنامه نویس‌های مختلف به اشتراک بگذاری همیشه این سوال وجود داره که دقیقا چطور میشه روند build رو یه جوری از وابستگی به سیستم عامل و حتی پلتفرم آزاد کرد. یه موضوع دیگه‌هم اینه که چطور میشه برای برنامه نویسان این آزادی رو ایجاد کرد که از IDE مورد علاقه‌شون استفاده کنند.

برای جواب به این سوالات و خیلی سوالات دیگه جامعه متن باز پروژه‌ای به نام cmake ایجاد کرده که ویژگی‌های خیلی خوبی داره و همچنین یادگیریش به نسبت آسونه!

ویژگی‌های cmake

خب اگه بگم ویژگی‌های cmake رو بصورت خلاصه بگم اینها هستن

  • امکان کامپایل‌کردن کد بدون در نظر گرفتن محل کد
  • امکان کامپایل‌کردن کد روی سیستم‌عاملهای مختلف
  • امکان تشخیص محل فایل‌ها، کتابخانه‌ها
  • مدیریت وابستگی ها
  • امکان تولید فایل‌های make برای سیستم‌های مختلف و تولید پروژه برای IDEهای مختلف

کاری که من با cmake انجام دادم

کاری که من با کم cmake انجام دادم رو سعی میکنم براتون توضیح بدم. خب ما یه کد داشتیم که برای سه تا پلتفرم سخت افزاری مختلف با سه تا کامپایلر مختلف به سه دسته کتابخانه مختلف کامپایل و لینک میشد. کد تمام این پروژه‌ها یکسان بود اما فقط توسط کامپایلرهای مختلف توی محیط netbeans کامپایل میشد. کاری که انجام دادم این بود:

  • ابتدا پروژه فعلی رو تنها برای یک پلتفرم به cmake تبدیل کردم
    • کامپایلر استاندارد رو به کامپایلر دلخواه تبدیل کردم
    • آدرس کتابخانه‌ها و header فایلهای استاندارد رو عوض کردم
    • بصورت اتوماتیک لیست تمام فایلهای پروژه استخراج میشه
  • با استفاده از پارامترها و ساختار منطقی که cmake ساپورت میکنه دو تا پلتفرم دیگه رو اضافه کردم
    • یه متغیر کنترلی تعریف کردم
    • با استفاده از متغیر کنترلی و if همه موارد بالا رو برای هر پلتفرم تعریف کردم
    • اسم خروجی باینری و فولدر اون رو بر اساس متغیر کنترلی تعیین کردم.

حالا با این حال من تنها یک فایل دارم که باهاش کار سه تا پروژه رو انجام میدم که خب این خیلی جالب و جذابه

همین!

اینم یه تجربه پراکنده دیگه!

امروز با یه زبان جدید آشنا شدم که اسمش lua است. این زبان رو قبلا تو کانفیگ کردن nginx و جاهای دیگه هم دیده بودم. این زبان یک زبان مفصریه و یعنی کامپایلری نداره و زمان اجرا تفسیر و اجر میشه. این زبان به نسبت ساده است و با زبان‌هایی مثل javascript و scheme مقایسه میشه. چند روز پیش هم که داشتم توی اینترنت میگشتم دیدم که یکی از ویژگی‌های این زبان اینه که شما میتونی توی یک برنامه دیگه از اون استفاده کنی. یعنی مفسرش به برنامه اضافه میشه و برنامت میتونه به با استفاده از lua برنامه ریزی بشه و مثلا plugin براش طراحی بشه.

کل مساله ای که من میخواستم حل کنم و به نظرم lua برای این کار مناسب اومد اینه که، قراره برنامه‌ای نوشته بشه که بصورت داینامیک بشه منطق کسب و کار رو توش عوض کرد. یعنی اینکه تا دیروز براساس روند a عمل میشده و امروز روند b باید عمل بشه. راه‌حل‌های زیادی برای این مساله وجود داره که در جامع ترین حالتش شما باید یه زبان توصیف مخصوص به خودت درست کنی و از اون استفاده کنی تا منطق کسب و کار رو پیاده‌سازی و تست بکنی. خب این روش الان توی تقریبا همه‌ی سیستم‌های مدیریت روند‌های کسب و کار وجود داره ولی من به ذهنم رسید وقتی یه چیزی مثل lua وجود داره و به راحتی با برنامه‌ی شما integrate میشه چرا بایستی من با تجربه و توان محدودم بخوام یه شبه زبان برنامه نویسی طراحی کنم. یه چیز دیگه که باعث شد به استفاده از lua فکر کنم این بود که  مثلا یه بخش از برنامه رو توی یه زبان دیگه بنویسی و فقط توی lua از اون استفاده کنی. این باعث میشه کارهایی که نیاز به کارایی و این چیزا دارن در زبانه دیگه طراحی بشن و فقط lua اونها رو سر هم کنه.

بعد گشتم و سعی کردم شواهدی در اینترنت پیدا کنم که ایده‌ای که به ذهنم رسیده آیا درسته یا نه. دیدم که مثلا در طراحی بازی خیلی از این ویژگی استفاده وعملا lua یک زبان برنامه‌نویسی محبوب در بین توسعه دهنده‌های بازی هست. یا دیدم که نرم‌افزاری به نام freeswitch که برای راه‌کاری تلفنی مبتنی بر voip هست از lua  به عنوان زبان طراحی روند تماس استفاده میکنه. یا با استفاده از lua شما میتونی nginx رو کنترل کنی. همچنین دیدم یه جایی مثل cisco برای سطوح دسترسی پویا از این زبان استفاده کرده. حتی lua یک سرور مثل node.js به نام luvit داره اما به اون مشهوری نیست.

همه این‌ها مطمئنم کرد که این ایده در صورت عملیاتی شدن خیلی بد نیست و باید یه طرح اولیه ازش پیاده‌سازی بشه و بعد تصمیم گرفته بشه که دقیقا چه اتفاقی بیفته.

همین!

اینم یه تجربه پراکنده دیگه!

من مدت‌هاست که به عنوان یکی از کارهای اصلی به زبان C برای سیستم‌های Embeded برنامه می‌نویسم. یعنی یه دستگاه محدود رو آماده میکنم که یه کار خاص رو انجام بده.

یکی از بزرگترین ویژگی‌های این دستگاه‌ها اینه که حافظه محدودی دارن و بعضی وقت‌ها بایستی حواس برنامه نویس به اینکه اولا چقدر حافظه مصرف شده و دوما اینکه متغیرها‌ی برنامه ای که مینویسه کجای حافظه تعریف میشن باشه.

اگه با اسمبلی آشنا باشید هر برنامه از سه قسمت Data, Code, Stack تعریف میشه. که خود  Data Segment هم از سه بخش Heap, Data, BSS تشکیل میشه. که توضیح هرکدوم این بخش‌ها داستان متفاوتی داره. حالا توی شبه کد پایین توضیح میدم که  اینها با هم چه تفاوتی داره

توی این شبه کد متغیر global به نام a وجود داره که توی data و یا ‌BSS تعریف میشه. متغیر b چون یک متغیر محلیه توی stack تعریف میشه. متغیر c یک متغیر محلی استایتک هست و به دلیل استاتیک بودنش توی data و یا ‌BSS تعریف میشه.  پوینتر d همه به یه آدرس توی heap اشاره میکنه چون این متغیر بصورت داینامیک تعریف شده و متغیر داینامیک در heap درست میشه. تفاوت data و BSS در اینه که متغیرهایی که مقدار اولیه غیر صفر دارن توی data تعریف میشن و متغیرهایی که مقدار اولیه ندارن و یا صفرن توی BSS تعریف میشن.

حالا مشکلی که وجود داشت اینه که من متغیرهای بزرگی توی متن تابع هام داشتم که باعث میشد حجم محدود stack موجود پر بشه و نرم افزار به خطای زمان اجرا بر بخوره. که با تغییر اونها به متغیرهای static محل نگهداری اونها به BSS یا Data تغییر مکان پیدا کرد و مساله حل شد.

همین!

با سلام

یکی از بزرگترین مشکلاتی که من در برنامه نویسی فارسی در زبان سی داشتم تبدیل کدپیجهای مختلف فارسی به یکدیگر است. معروفترین کدپیج همان ایرانسیستم است و مشکل وقتی پیش می آید که قرار است تبدیل از یونیکد و ویندوز ۱۲۵۶ به ایرانسیستم یا واژه نگار انجام شود. دلیل نیاز به این تبدیل عدم پشتیبانی زبان سی استاندارد از کارکترهای دو بایتی برای زبان فارسی(یونیکد) است. حالا در سیستم عاملهای جدید معمولا این مشکل با معرفی نوع داده ای wchar حل شده ولی این مشکل وقتی با سخت افزار خاصی که تنها از سی استاندارد پشتیبانی میکند بیشتر میشود.

یکی از راه حلها استفاده از روشهای گوسفندی(Brute-Force) است. یعنی تبدیل با نوشتن حجم زیادی کد برای رفع این مشکل. تفریبا هیچ راه حل دیگری وجود ندارد اما نرم افزار کد بازی به زبان جاوا وجود دارد که حجم زیاد از کد را نوشته و تنها نیاز به تبدیل کد از جاوا به سی است.

این نرم افزار(فارسیدو) را میتوان از سایت آقا هومن برادران دانلود کرد. آدرس این سایت در زیر آمده است.

http://farsido.hoomanb.com/

پ.ن. دیدن خود سایت آقای برادران هم خالی از لطف نیست