עבור לתוכן

כמה שאלות של מתחיל בתכנות DLL ב-VC

Featured Replies

פורסם

בעיקרון מה שאני מנסה להבין זה את הניהול זיכרון של אותה ספריה

האם כל תהליך שקורא לספריה הזאת יוצר עותק שלו של כל המשתנים שלה

נגיד אני מגדיר משנה גלובלי var

האם עבור כל תהליך נוצר משתנה var שונה

כלומר אם ה-DLL שלי נראה ככה

int var;

BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved )

{

if ( fdwReason == DLL_PROCESS_ATTACH ) var = func();

if ( fdwReason == DLL_PROCESS_DETACH ) print var

}

func פונקציה כלשהי

האם כל תהליך שמשתמש ב-DLL הזה ידפיס ביציאה שלו את הערך שניתן לו בטיענה שלו?

אותה שאלה לגבי משתנה לוקאלי - כלומר עבור הקוד הבא

BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved )

{

int var;

if ( fdwReason == DLL_PROCESS_ATTACH ) var = func();

if ( fdwReason == DLL_PROCESS_DETACH ) print var

}

האם var ממשיך לחיות עם עד שלא מגיעים ל-DETACH או שמקרה הזה ההדפסה ביציאה תדפיס שטויות?

פורסם

התשובה לשאלה השנייה שלך פשוטה, ותופסת לגבי כל משתנים לוקאלים לפונקציה. אגב, כל זה יהיה לך מאוד ברור אם רק תכתוב תוכנית קטנה שקוראת לפונקציה ופשוט תסתכל על ה- disassembly שלה. ובכן, התשובה היא שמשתנים לוקאלים נשמרים על ה- stack של ה- thread שקרא לפונקציה. לפני הקריאה נוצר מה שנקרא stack frame - מעין מקום מיוחד על הstack שנועד להכיל את כל המשתנים הלוקאלים של הפונקציה הנקראת. עם יציאה מהפונקציה, ה- frame נסגר כי הפונקציה כבר נקראה ולא צריכים את המקום יותר. יש מיליון נואנסים בנושא הזה (באיזה סדר המשתנים נדחפים ל- stack, מי דוחף אותם ל- stack, האם מאפסים stack frame לפני השימוש וכד') ואני יכול רק להמליץ לך לקרוא קוד assembly כי הדבר נעשה בצורה שונה בכל סביבה \ קומפיילר. אם תסתכל על איך הדבר נעשה בהגדרות הדיפולטביות של vc6 תראה שיש שימוש בשני רגיסטרים: ebp ו- esp כאשר סדר הפעולה נראית בערך כך:

דחוף כתובת חזרה ל- stack (כדי לדעת לאיזה קוד לקרוא עם יציאת הפונקציה)

דחוף את ebp ל- stack (כדי לדעת לאחזר את ה- stack frame הישן)

שים את esp ב- ebp (להתחיל לבנות את החלק התחתון של ה- stack frame החדש)

תפחית מ- esp את כמות הבתים שהפונקציה צריכה (שים לך שה- stack גדל כלפי מטה בכתובות וסופו בעצם כתובת נמוכה יותר מתחילתו)

תמלא את ה- stack החדש ב- 0xCC (זה רק לצורך debugging וכמובן צורך הרבה משאבים.. למרות זה לא משנה ב- PC).

לגבי השאלה השנייה - לא ידעתי את התשובה off hand כי כבר הרבה זמן לא תיכנתי תחת windows.. אבל msdn לא מאכזב ונותן את התשובה:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/dynamic_link_library_data.asp

במילים פשוטות, process שעושה LoadLibrary בעצם מקצה זכרון עבור ה- data segment של ה- DLL. שם יש את כל המשתנים הגלובאלים המאותחלים (RW), הקונסטנטים (RO) והלא מאותחלים (ZI). שים לב שהזכרון משוחרר עם ה- detach - מה שאומר שאינך יכול להשתמש בזה לאחר מכן.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים