לדלג לתוכן

פתרון ארכיטקטורות וחוזי WinAPI

משתנה שאינו נמצא נשאר בצורתו המקורית לפי חוזה ההרחבה. זו אינה בהכרח שגיאת API. אם המוצר דורש שכל משתנה יהיה קיים, צריך להוסיף בדיקת משמעות נפרדת במקום לפרש כל תוצאה שהכילה סימני אחוז ככשל מערכת.

מתאם בדיקה פשוט יכול להפריד את הלולאה מפונקציית המערכת. הקטע הבא מדגים callback שמחזיר בכל ניסיון גודל גדול יותר; הוא אינו מחליף את כל ה־wrapper אלא את פעולת המדידה והמילוי שלו.

struct GrowingResult {
    DWORD operator()(const wchar_t*, wchar_t*, DWORD capacity) const {
        return capacity == 0 ? 4 : capacity + 1;
    }
};

הבדיקה צריכה להזריק את האובייקט לתוך אותו אלגוריתם, ולוודא שהוא מגיע לכשל אחרי מספר הניסיונות שהוגדר. אין צורך לייצר race אמיתי במשתני הסביבה כדי לבדוק את מדיניות הגידול.

ב־Windows x64 גם long וגם DWORD הם בני ארבעה בתים, בעוד pointer הוא בן שמונה. ב־x86 pointer הוא בן ארבעה. התוצאה אינה תלויה רק בגודל RAM או בארכיטקטורת החומרה המארחת, אלא ביעד הבנייה ובסביבת התהליך.

פעולה חוזה שצריך לשמור
פתיחת קובץ באמצעות CreateFileW הכשל הוא INVALID_HANDLE_VALUE; הצלחה שמחזיקה handle מחייבת CloseHandle
יצירת event באמצעות CreateEventW הכשל הוא null; הצלחה מחייבת CloseHandle
קבלת נתיב module הקיבולת נמדדת ביחידות wchar_t; ערך הצלחה רגיל אינו כולל null, וצריך לזהות חיתוך לפי החוזה
הרחבת משתני סביבה הגודל והערך המוחזר נמדדים ביחידות טקסט; תוצאה מלאה כוללת null

הטבלה היא נקודת התחלה לקריאת תיעוד, ולא תחליף לפרטי המקרים המיוחדים. בפרט, GetModuleFileNameW דורשת תשומת לב לתוצאה שווה לקיבולת, והחוזה ההיסטורי שלה אינו זהה בכל גרסת Windows.

הבדיקה הנכונה של HRESULT היא FAILED(hr) לזיהוי כשל. לאחר מכן אפשר לבדוק hr == S_FALSE כדי לטפל במשמעות הספציפית. הצלחה יכולה לומר שהפעולה הסתיימה בלי שינוי, או שתנאי מסוים אינו מתקיים, בהתאם ל־API.

הפתרון לא מעביר HRESULT אל GetLastError. מקור השגיאה הוא הערך שחזר מהפעולה, והמרה בין משפחות קודים דורשת מנגנון מתועד.