הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
איזה מתכנת שפוי יכול לפתח תחת Windows?
לאחרונה אני נחשף יותר יותר לנפלאותיה של מערכת הפעלה של Microsoft והכלים המתוחכמים והמשובחים שיש לך כמו Visual Studio. אני אביא רשימה קצרה של תסכולים קטנים שגורמת לי לתחושה שאני לא רוצה לפתח עבורה.
Berkeley Sockets -- לא בבית ספרינו
לאחרונה יוצא לי לכתוב לא מעט קוד Cross Platform, בפרט הקוד שמתעסק ב-Soketים. כמובן אני לא אספר על כל השטויות כמו שימוש ב-closesocket() במקום close() או ש-write(2) הרגיל לא עובד אתם ושאר נפלאות עולם ה-Windows. אני אדבר על API החדש שמפתחי Microsoft סוף-סוף הכניסו ל-Windows Vista ו-Windows Server 2008.
כפי שאתם יודעים עד היום כל מי שכתב תחת Windows היה צריך להשתמש ב-select() על מנת לבצע פעולות א-סינכרוניות. poll() זאת הייתה קריאה מסובכת מידי. אבל, הללויה עם יציאת Windows Vista אנחנו יכולים סוף-סוף ליהנות מהפונקציה החדשה שלא מגבילה אותנו במספר ערוצים שאנחנו יכולים לעקוב אחריהם. אבל מה? היא לא נקראת poll אלא WSAPoll אפילו שהיא זהה אחד לאחד ל-poll() המוכר לנו מסביבת POSIX.
אתם רוצים לבצע connect() בצורה א-סינכרונית, בבקשה, רק אין לכם ioctl תשתמשו ב-WSAIoctl. אתם רוצים לדעת אם הפעולה הושלמה בהצלחה? תבדקו אותה עם select ולא עם getsockopt כמו בשאר מערכות POSIX (נבדק ב-Linux, OpenVMS, HP-UX). כמובן שגם inet_iton איננה, רק פונקציה שלא מומלצת יותר לשימוש inet_addr ועוד ועוד ועוד.
האם סיימתי? לא!
לקחתי את כל הדברים האלו בחשבון עשיתי שיעורי בית, קימפלתי את היישום בעזרת Mingw והכל עובד יפה! עכשיו הגעתי ל-Visual Studio 2005 החדש והנוצץ ומקמפל: "אין סימבול _WSAIoctl במערכת..." WTF? בודק, winsock2 מחובר, כל שאר הקריאות עובדות... מה לא עובד? מנסה לשחק, לשנות עוד... לא עובד. קורא למומחה Windows... מסתבר שלא עשיתי incude ל-winsock2! סבבה! מכניס את ה-include הארור הזה ו... אלף הערות ושגיאות על כך שכל מיני סימבולים מוגדרים מחדש... WTF#%#@%$ מחליף את ה-include של windows ו-winsock2 ביניהם... פלא, פלא עובד!
הסבירו לי, כיצד, בשנת 2008 עדיין סדר includeים משנה?
מי צריך C99?
כמובן שבהעברת קוד ממערכות POSIX ל-Windows (או ליתר דיוק VS2005) ובטיפול בכמה includeים זה לא נגמר.
מסתבר שהקומפיילר של VS לא תומך ברכיבים בסיסיים של C99, למשל, הגדרת משתנה בכל מקום.
מה הכוונה:
int foo(int x)
{
x=x+2;
int y=2*x+10;
return y;
}
כלומר הקוד לעיל לא יעבוד אפילו שהוא כתוב לפי הדרישות של C99 וכבר עברו כמעט 9 שנים מאז שזה הוכנס לתקן.
עכשיו, רוצים snprintf() כמו שהוגדר ב-C99? לא תקבלו, יש רק _snprintf() וזהו... כלומר, אם רוצים לכתוב קוד "בטוח מ-Buffer Overflow" תתכוננו להרבה ifdefים או defineים. רוצים uint16_t או uint64_t המוגדרים בתקן C99? לא תקבלו, תשתמשו בחלופות ש-MS מספק.
כלומר, אם אתה רוצה לכתוב ב-C תחת Windws אתה חייב להישאר איפה שהוא בסוף שנות ה-80 תחילת 90.
אז כיצד מתכנת שפוי אמור לפתח תחת Windows? לא יודע, מה שכן, אני אפסיק להתלונן על OpenVMS כי היא מתחילה להיראות הרבה יותר ידידותית למפתח.
תגובות
"אז כיצד מתכנת שפוי אמור לפתח תחת Windows? לא יודע, מה שכן, אני אפסיק להתלונן על OpenVMS כי היא מתחילה להיראות הרבה יותר ידידותית למפתח."
עובר לדוט נט?
האם לחסוך ממך הרצאה שלמה למה ".net" זאת טכנולוגיה שמתאימה ליישומים מסוימים בלבד? או לחסוך ממך?
למרות ש-Microsoft דוחפים את הטכנולוגיה הזו לכל חור (והיא גם ממש לא רעה) היא ממש לא מתאימה לכל דבר. (ראה ערך Vista).
באמת ניתן להשתמש ב-#ifdefים כדי להתמודד עם הבעייה ספציפית לחלונות. אפשרות אחרת היא להשתמש <a href="http://www.shlomifish.org/open-source/portability-libs/" rel="nofollow">בספריות אבסטרקציה</a> שכאמור מקלות על המתכנת, בכך שהן נותנות ממשק אחיד לכל המערכות, כולל לא פעם טיפוסים אחידים. אתה <a href="http://art-blog.no-ip.info/wp/index.php/2008/02/01/os_api_and_all_between_them/" rel="nofollow">טענת ש-POSIX היא שכבת תאימות מספיקה</a>, ואולי עכשיו אתה מבין מדוע זה לא נכון.
בקוד שלי בעבודה הוגדרה שכבת תאימות משלנו, הפועלת על לינוקס, חלונות ומערכות הפעלה אחרות, ואני נאלץ להשתמש בה ולעיתים גם לתחזק את הקוד שלה שיחודי ללינוקס.
דרך אגב, החסרון של הצהרה על משתנים באמצע הפונקציה הוא דבר שפחות חסר לי מ-C99. במקום עבודה קודם, הוטעלה עלי משימה לכתוב קוד C, שבין השאר יועד גם לרוץ בקרנלים של לינוקס וחלונות, וחיפשתי דרך לבצע איתחול סימבולי לשדות של structים, ובעוד שב-gcc תכונה כזאת קיימת כבר זמן רב, היא לא קיימת ב-Visual C בשום אופן וצורה, אף שהיא כבר מוגדרת על ידי C99. שלא לדבר על inline functions ועוד.
זה מעצבן אותי מאוד שמיקרוסופט מזניחים לחלוטין את יכולות ה-ANSI C של המהדר שלהם, ובאותו הזמן מוסיפים תכונות רבות מיותרות ל-C++ (תוך ניפוח התקן), כמו איסוף אשפה. עכשיו, אילו רק gcc ו-g++ היו תומכים ב-win64.
לכתוב קוד C או C++ שיהיה פורטבילי לחלוטין וגם יעשה דברים לא טריוויאליים זו משימה קשה. לא בלתי אפשרית אבל קשה.
אה, ודרך אגב, אם ב-WordPress עסקיננו, האם ניתן לדאוג שתהיינה להערות כאן מראה מוקדם (Preview)?
דווקא זה משכנע אותי שזה די נכון, כי הן ב-OpenVMS הן ב-HP-UX והן ב-Linux כמעט לא הייתי צריך להתאמץ.
שוב, כמובן יש הבדלים בין מערכות הפעלה תואמות POSIX בנקודות מסוימות אבל, יש הבדל בין מה שקורה במערכות דומות (או אפילו לא מי יודע מה דומות כמו VMS) ל-UNIX לבין מה שקורה ב-Windows.
שוב, XP לא תואמת POSIX בעליל ואני ממש מתרגז בכל פעם כשאני מגלה דברים "חדשים" על Windows.
לגבי ספריות תאימות. לא צריך אותן (או כמעט לא צריך אותן) כשמדובר במערכות תואמות POSIX. ולגבי Windows? שימות, אמן.
כלומר, אם לא הייתי צריך לדאוג לחלונות, או חלונות היו תואמות POSIX כמו שצריך לא הייתי צריך לשבור את הראש שלי בכל פעם מחדש.
מה אני יכול להגיד, צודק... צריך
הוסף תגובה:
חובה לאפשר JavaScript כדי להגיב.