ارتباط لوا و #c با استفاده از ++c

the_king

مدیرکل انجمن
سلام
واقعا ممنونم استاد علی:rose:
ولی من این خط رو توی سی شارپ متوجه نشدم دقیقا چی کار میکنه؟ :

کد:
var sptr = Marshal.ReadIntPtr(ptr, i * IntPtr.Size);

و علاوه بر اون ، همینطور این پروپرتی IntPtr.Size چیه و چی رو محاسبه میکنه؟
لابد یادتون هست که آرایه ای که به تابع ارسال میشه آرایه ای از اشاره گر ها است که هر کدوم اشاره گر یک رشته هستند. با ReadIntPtr این اشاره گر ها رو از آرایه یکی یکی می خوانید، پارامتر دوم Offset ئه که بر حسب بایت ئه، عملا ptr + offset* آدرسی رو تعیین می کنه که قراره ازش خونده بشه، یعنی offset بایت جلوتر از جایی که ptr اشاره می کنه. مشخص می کنه که جایی که قراره اشاره گر رو از داخلش بخوانید چند بایت بعد از آدرس ptr قرار داره، با توجه به اینکه در برنامه 32 بیتی اشاره گر ها 4 بایتی هستند، اشاره گر اول در Offset ئه 0 قرار داره، اشاره گر دوم در 4 و سومی در 8 و چهارمی در 12 و ... برای اینکه کد اصولی نوشته بشه بجای i * 4 از IntPtr.Size استفاده میشه که میگه اشاره گر ها چند بایتی هستند، اگر این متد در محیط 32 بیتی اجرا بشه 4 بر می گردونه و اگر در محیط 64 بیتی باشه 8 رو بر می گردونه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
ممنون استاد علی
حالا اگه بخوام در سی شارپ ، رشته (رشته ی سی شارپ یا managed) رو توی اشاره گری (از نوع unmanaged) کپی کنم ، از چه متدی استفاده کنم؟
متد StringToCoTaskMemUni انگار به درد این نمیخوره و اشاره گر برمیگردونه . در صورتی که میخوام توی اشاره گر خواصی کپی کنه
باید رشته رو اول به آرایه ای از کاراکتر ها تبدیل کنم و بعد با متد Copy این کار رو کنم؟
-----------------
بعد اینکه در لوا ، در خط
کد:
myTable_Hdl:SetArrayType(MEMEX_ARR_DWORD);
بجای MEMEX_ARR_DWORD میتونم از MEMEX_ARR_INT استفاده کنم؟ آخه گفتین فضای اشغالی شون یکی هه
نمیدونم بخاطر چی هست که در کدی که من نوشتم (همون کد شما هست ولی آرایه ای اش کردم) ، گاهی اوقات ، بعد از اجرای کدهای سی شارپ (در dll) و وقتی دوباره کنترل میاد توی کدهای لوا ، برنامه کرش میکنه . البته گاهی اوقات.
کدها هم دقیقا همونه :

کد:
myArrayLua = {[0]="salam", [1]="khobi?", [2]="chi kar mikoni?", [3]="manam khobam",[4]= "khodahafez"};
ptrToElemArrSize_Int = (#myArrayLua) * 4;  -- be tedade azaye araye reshteh , chon esharegarha 4 byte (int) eshghal mikonan , 4 byte faza gereftim
myTable_Hdl = MemoryEx.AllocateEx(ptrToElemArrSize_Int);
if (myTable_Hdl == nil) then
return;
end

myTable_Hdl:SetArrayType(MEMEX_ARR_DWORD);  -- chon aza arayeh, hamon esharegar ke adad hastan, data type ro int ya adad gereftim
mainArrPointer = myTable_Hdl:GetPointer();
elemSizeNeed = {};
elemStringArray_Hdl = {};
elemStringArrPointer = {};
for i=0,#myArrayLua do
elemSizeNeed[i] = ( String.Length(myArrayLua[i]) ) * 2;  -- tedad byte haye esghali kole reshteh
elemStringArray_Hdl[i] = MemoryEx.AllocateEx(elemSizeNeed[i]);
    if (elemStringArray_Hdl == nil) then
    return;
    end
   
    elemStringArrPointer[i] = elemStringArray_Hdl[i]:GetPointer();
    MemoryEx.String(elemStringArrPointer[i], -1, MEMEX_UNICODE, myArrayLua[i]);
   
    myTable_Hdl[i] = elemStringArrPointer[i];
end

for i=0,#myArrayLua do
myStringRes = MemoryEx.String(elemStringArrPointer[i], -1, MEMEX_UNICODE);
Dialog.Message(#myArrayLua.."  "..i, myStringRes, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
end

----------------------------
dllHdl = Library.Load("ClassLibrary2.dll");
if (dllHdl) then
dllHdl.StringArrayTest(mainArrPointer, #myArrayLua+1);
dllHdl:Close_();
end
---------------------------
for i=0, #myArrayLua do
elemStringArray_Hdl[i]:Free();
end
myTable_Hdl:Free();

و


کد:
[DllExportAttribute("StringArrayTest", CallingConvention.StdCall)]
        public static void StringArrayTest(IntPtr mainStringArrPtr, int arrayLength)
        {
            string[] stringArrayCS = new string[arrayLength];
            for (int i = 0; i < arrayLength; i++)
            {
                IntPtr ptrMoveInElement = Marshal.ReadIntPtr(mainStringArrPtr, i * 4);
                stringArrayCS[i] = Marshal.PtrToStringUni(ptrMoveInElement);
            }
            MessageBox.Show(string.Join("\n", stringArrayCS), "in c#");
        }
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی
حالا اگه بخوام در سی شارپ ، رشته (رشته ی سی شارپ یا managed) رو توی اشاره گری (از نوع unmanaged) کپی کنم ، از چه متدی استفاده کنم؟
متد StringToCoTaskMemUni انگار به درد این نمیخوره و اشاره گر برمیگردونه . در صورتی که میخوام توی اشاره گر خواصی کپی کنه
باید رشته رو اول به آرایه ای از کاراکتر ها تبدیل کنم و بعد با متد Copy این کار رو کنم؟
به کاراکتر یا به بایت تبدیل کنید. چون بصورت مشخص با Unicode یا ANSI کار می کنید بهتره به بایت تبدیل بشه.
کد:
            var s = "Test";
              var bytes = Encoding.Unicode.GetBytes(s + "\0");
            Marshal.Copy(bytes, 0, sptr, bytes.Length);

بعد اینکه در لوا ، در خط
کد:
myTable_Hdl:SetArrayType(MEMEX_ARR_DWORD);
بجای MEMEX_ARR_DWORD میتونم از MEMEX_ARR_INT استفاده کنم؟ آخه گفتین فضای اشغالی شون یکی هه
اشاره گر حافظه 32 بیتی فاقد علامت ئه اما نمیدونم با آدرس های حافظه در اتوپلی بصورت اعداد علامتدار (مثبت منفی signed) برخورد میشه یا بدون علامت (unsigned). بعید نیست که علامت دار باشه.
به همین جهت مطمئن نیستم DWORD معادل INT باشه. INT لابد علامت دار ئه ولی ممکنه DWORD فاقد علامت باشه. اگه آدرس حافظه در محدوده اعداد علامت دار مثبت نباشه بصورت یک عدد منفی برگردونده میشه که شاید درست عمل نکنه. شایدم اصلا درست این باشه که از INT استفاده کنید، نمیدونم. مهم اینه که فرضا اگه آدرس حافظه 1- باشه، معادل 4294967295 بدون علامت ئه، شکل باینری شون هم عینا یکی ئه. مهم اینه که معادل باینری اش در حافظه درست قرار بگیره و البته خطا نده.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام استاد علی
با توابع api یعنی با تابع ChooseFont که در فایل Comdlg32.dll هست ، میخوام دیالوگ فونت رو فراخونی کنم وبعد از زدن ok از دیالوگ فونت ، اسم فونت ای که کاربر انتخاب کرد رو بگیرم ولی نمیدونم توی کد زیر باید چی کار کنم .
از پلاگین AMSWMemory استفاده کردم که در لینک زیر هست :
AMSWMemory.rar


کد:
 _LogFont = Memory.CreateStructure("long, long, long, long, long, byte, byte, byte, byte, byte, byte, byte, byte, long");  -- استراکچر مربوط به اطلاعات LOGFONT
Memory.SetStructureData(_LogFont, 1, 0, 0, ""); -- lfHeight
Memory.SetStructureData(_LogFont, 2, 0, 0, ""); -- lfWidth
Memory.SetStructureData(_LogFont, 3, 0, 0, ""); -- lfEscapement
Memory.SetStructureData(_LogFont, 4, 0, 0, ""); -- lfOrientation
Memory.SetStructureData(_LogFont, 5, 0, 400, ""); -- lfWeight
Memory.SetStructureData(_LogFont, 6, 0, 1, ""); --Italic
Memory.SetStructureData(_LogFont, 7, 0, 1, "");  --Underline
Memory.SetStructureData(_LogFont, 8, 0, 1, "");  --StrikeOut
Memory.SetStructureData(_LogFont, 9, 0, 0, "");  --Ansi_CHARSET
Memory.SetStructureData(_LogFont, 10, 0, "OUT_TT_PRECIS", "");  --OutPrecision
Memory.SetStructureData(_LogFont, 11, 0, "CLIP_DEFAULT_PRECIS", "");   --ClipPrecision
Memory.SetStructureData(_LogFont, 12, 0, 4, "");    --FontQuality
Memory.SetStructureData(_LogFont, 13, 0, 1, "");    --PitchAndFamily  FIXED_PITCH
Memory.SetStructureData(_LogFont, 14, 0, 0, "");    --FaceName

 str = Memory.CreateStructure("long, long, long, long, long, long, long, long, long, long, long, long, long, long, long");  -- استراکچري که مربوط به اطلاعاتاستراکچر CHOOSEFONT هست
Memory.SetStructureData(str, 1, 0, Memory.Size(str), "");  -- lStructSize
Memory.SetStructureData(str, 2, 0, Application.GetWndHandle(), "");  -- hwndOwner
Memory.SetStructureData(str, 4, 0, _LogFont, "");  -- lpLogFont
Memory.SetStructureData(str, 5, 0, "0x00000100", "");  -- iPointSize
Memory.SetStructureData(str, 6, 0, "0x00000100", "");   --Flags
Memory.SetStructureData(str, 7, 0, "255", "");  -- rgbColors
Memory.SetStructureData(str, 8, 0, "", "");  -- lCustData
Memory.SetStructureData(str, 9, 0, "", "");  -- lpfnHook
Memory.SetStructureData(str, 10, 0, "", "");  -- lpTemplateName
Memory.SetStructureData(str, 11, 0, "", "");  -- hInstance
Memory.SetStructureData(str, 12, 0, "", "");  -- lpszStyle
Memory.SetStructureData(str, 13, 0, "0x0100", "");  --nFontType  BOLD_FONTTYPE
Memory.SetStructureData(str, 14, 0, 6, "");  -- nSizeMin
local isOkSelect = DLL.CallFunction("comdlg32.dll", "ChooseFontA", str, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);  -- فراخوني تابع ChooseFont که در فايل Comdlg32.dll هست

if (tonumber(isOkSelect) == 1) then  -- اگر کاربر ok را انتخاب کرد
     fPtr = Memory.GetStructureData(_LogFont, 14, 0, "");  -- اطلاعات ذخيره شده در چهاردهمين استراکچر استراکچر _LogFont رو بگير
     Dialog.Message("Notice", fPtr, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
end

میدونم حوصله ی اتوپلی رو ندارین ولی اگه راهنمایی کنین ، ممنون میشم
در خط اول یعنی Memory.CreateStructure ، به تعداد درون رشته هایی که نوشتیم (یعنی 14 تا) ، استراکچر که هر کدوم از نوع هایی که در رشته هستن ، ساختیم . خروجی این تابع ، اشاره گری به همین استراکچر هست . این استراکچر مربوط به اطلاعات LOGFONT هست :
LOGFONT structure (Windows)
با متد Memory.SetStructureData ، برای هر استراکچر ، مقداری میتونیم بدیم
14 تا استراکچر میخواد که اگه اشتباه نکنم ، آخریش یعنی lfFaceName ، باید رشته (آرایه ای از Char) قبول کنه (اینکه هر استراکچر ، مربوط به کدوم آرگومان هست رو جلوش نوشتم . توضیح و کامنت در لوا با علامت -- شروع میشه) . اولا نمیدونم چرا این آرگومان (lfFaceName) ، با رشته در لوا سازگار نیست (یا من نمیدونم چجوری هه) یعنی وقتی مقدار "Arial" رو بهش میدم :

کد:
 Memory.SetStructureData(_LogFont, 14, 0, "Arial", "");    --FaceName
کار نمیکنه و موقع باز شدن دیالوگ فونت ، فونت Arial انتخاب نمیشه
نکته ی دیگه در این استراکچر اینکه انگار هیچ کدوم از طلاعاتی که دادم یعنی مثلا استراکچر شماره ی 7 که مربوط به Underline هست رو 1 میذارم یعنی true میکنم ، موقع باز شدن فونت ، تیک این گزینه زده نمیشه !

در استراکچر بعدی ، اطلاعات مربوط به استراکچر CHOOSEFONT را دادم :
CHOOSEFONT structure (Windows)
طبعا در آرگومان چهارم یعنی lpLogFont ، استراکچر مربوط به متغییر LogFont_ را که استراکچر مربوط به اطلاعات LOGFONT بود را دادم.

حالا بعد از زدن ok در دیالوگ font ، کد داخل شرط اجرا میشه . با متد Memory.GetStructureData اطلاعات درون یک استراکچر رو میتونیم بخونیم . در این بدنه ی شرط ، میخوام اطلاعات مربوط به نام فونت ای که کاربر انتخاب کرد (و به طبع باید رشته باشه) رو بخونم . خوب اگه دکمه ی کنسل رو بزنیم یا دکمه ی ok رو بزنیم ولی نام فونت ای رو انتخاب نکنیم ، مقدار قبلی یعنی مقداری که در خط

کد:
 Memory.SetStructureData(_LogFont, 14, 0, 0, "");    --FaceName
مشخص کردیم یعنی مقدار صفر رو میخونه

ولی اگه نام فونت ای رو مشخص کنیم ، مقادیر ثابت ای توی خروجی این خط کد

کد:
     fPtr = Memory.GetStructureData(_LogFont, 14, 0, "");  -- اطلاعات ذخيره شده در چهاردهمين استراکچر استراکچر _LogFont رو بگير
یعنی در متغییر fPtr ذخیره میشه . مثلا اگه Arial رو انتخاب کنیم ، همیشه مقدار ثابت 1634300481 ذخیره میشه . چون مقدار ثابت هه ، پس نباید اشاره گر باشه (من فکر میکردم ، رشته یعنی آرایه ای از کاراکترهاست ، پس باید اشارهگر باشه ولی مقدارش همیشه ثابت هه)
پس انگار باید مقدار باشه . از طرفی هم نوع اش ansi هست و هر کاراتر یک بایت ذخیره میشه پس برای رشته ی Arial که 5 کاراکتر هست ، باید 5 بایت اشغال بشه ولی عدد 1634300481 اگه تبدیل به باینری بشه ، عدد ۱۱۰۰۰۰۱۰۱۱۰۱۰۰۱۰۱۱۱۰۰۱۰۰۱۰۰۰۰۰۱ که هشت بایت هست !!

کلا اینکه چجوری میتونم مقدار رشته ای که کاربر از دیالوگ font انتخاب میکنه رو دریافت کنم؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلام استاد علی
با توابع api یعنی با تابع ChooseFont که در فایل Comdlg32.dll هست ، میخوام دیالوگ فونت رو فراخونی کنم وبعد از زدن ok از دیالوگ فونت ، اسم فونت ای که کاربر انتخاب کرد رو بگیرم ولی نمیدونم توی کد زیر باید چی کار کنم .
از پلاگین AMSWMemory استفاده کردم که در لینک زیر هست :
AMSWMemory.rar


کد:
 _LogFont = Memory.CreateStructure("long, long, long, long, long, byte, byte, byte, byte, byte, byte, byte, byte, long");  -- استراکچر مربوط به اطلاعات LOGFONT
Memory.SetStructureData(_LogFont, 1, 0, 0, ""); -- lfHeight
Memory.SetStructureData(_LogFont, 2, 0, 0, ""); -- lfWidth
Memory.SetStructureData(_LogFont, 3, 0, 0, ""); -- lfEscapement
Memory.SetStructureData(_LogFont, 4, 0, 0, ""); -- lfOrientation
Memory.SetStructureData(_LogFont, 5, 0, 400, ""); -- lfWeight
Memory.SetStructureData(_LogFont, 6, 0, 1, ""); --Italic
Memory.SetStructureData(_LogFont, 7, 0, 1, "");  --Underline
Memory.SetStructureData(_LogFont, 8, 0, 1, "");  --StrikeOut
Memory.SetStructureData(_LogFont, 9, 0, 0, "");  --Ansi_CHARSET
Memory.SetStructureData(_LogFont, 10, 0, "OUT_TT_PRECIS", "");  --OutPrecision
Memory.SetStructureData(_LogFont, 11, 0, "CLIP_DEFAULT_PRECIS", "");   --ClipPrecision
Memory.SetStructureData(_LogFont, 12, 0, 4, "");    --FontQuality
Memory.SetStructureData(_LogFont, 13, 0, 1, "");    --PitchAndFamily  FIXED_PITCH
Memory.SetStructureData(_LogFont, 14, 0, 0, "");    --FaceName

str = Memory.CreateStructure("long, long, long, long, long, long, long, long, long, long, long, long, long, long, long");  -- استراکچري که مربوط به اطلاعاتاستراکچر CHOOSEFONT هست
Memory.SetStructureData(str, 1, 0, Memory.Size(str), "");  -- lStructSize
Memory.SetStructureData(str, 2, 0, Application.GetWndHandle(), "");  -- hwndOwner
Memory.SetStructureData(str, 4, 0, _LogFont, "");  -- lpLogFont
Memory.SetStructureData(str, 5, 0, "0x00000100", "");  -- iPointSize
Memory.SetStructureData(str, 6, 0, "0x00000100", "");   --Flags
Memory.SetStructureData(str, 7, 0, "255", "");  -- rgbColors
Memory.SetStructureData(str, 8, 0, "", "");  -- lCustData
Memory.SetStructureData(str, 9, 0, "", "");  -- lpfnHook
Memory.SetStructureData(str, 10, 0, "", "");  -- lpTemplateName
Memory.SetStructureData(str, 11, 0, "", "");  -- hInstance
Memory.SetStructureData(str, 12, 0, "", "");  -- lpszStyle
Memory.SetStructureData(str, 13, 0, "0x0100", "");  --nFontType  BOLD_FONTTYPE
Memory.SetStructureData(str, 14, 0, 6, "");  -- nSizeMin
local isOkSelect = DLL.CallFunction("comdlg32.dll", "ChooseFontA", str, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL);  -- فراخوني تابع ChooseFont که در فايل Comdlg32.dll هست

if (tonumber(isOkSelect) == 1) then  -- اگر کاربر ok را انتخاب کرد
     fPtr = Memory.GetStructureData(_LogFont, 14, 0, "");  -- اطلاعات ذخيره شده در چهاردهمين استراکچر استراکچر _LogFont رو بگير
     Dialog.Message("Notice", fPtr, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
end

میدونم حوصله ی اتوپلی رو ندارین ولی اگه راهنمایی کنین ، ممنون میشم
در خط اول یعنی Memory.CreateStructure ، به تعداد درون رشته هایی که نوشتیم (یعنی 14 تا) ، استراکچر که هر کدوم از نوع هایی که در رشته هستن ، ساختیم . خروجی این تابع ، اشاره گری به همین استراکچر هست . این استراکچر مربوط به اطلاعات LOGFONT هست :
LOGFONT structure (Windows)
با متد Memory.SetStructureData ، برای هر استراکچر ، مقداری میتونیم بدیم
14 تا استراکچر میخواد که اگه اشتباه نکنم ، آخریش یعنی lfFaceName ، باید رشته (آرایه ای از Char) قبول کنه (اینکه هر استراکچر ، مربوط به کدوم آرگومان هست رو جلوش نوشتم . توضیح و کامنت در لوا با علامت -- شروع میشه) . اولا نمیدونم چرا این آرگومان (lfFaceName) ، با رشته در لوا سازگار نیست (یا من نمیدونم چجوری هه) یعنی وقتی مقدار "Arial" رو بهش میدم :

کد:
 Memory.SetStructureData(_LogFont, 14, 0, "Arial", "");    --FaceName
کار نمیکنه و موقع باز شدن دیالوگ فونت ، فونت Arial انتخاب نمیشه
نکته ی دیگه در این استراکچر اینکه انگار هیچ کدوم از طلاعاتی که دادم یعنی مثلا استراکچر شماره ی 7 که مربوط به Underline هست رو 1 میذارم یعنی true میکنم ، موقع باز شدن فونت ، تیک این گزینه زده نمیشه !

در استراکچر بعدی ، اطلاعات مربوط به استراکچر CHOOSEFONT را دادم :
CHOOSEFONT structure (Windows)
طبعا در آرگومان چهارم یعنی lpLogFont ، استراکچر مربوط به متغییر LogFont_ را که استراکچر مربوط به اطلاعات LOGFONT بود را دادم.

حالا بعد از زدن ok در دیالوگ font ، کد داخل شرط اجرا میشه . با متد Memory.GetStructureData اطلاعات درون یک استراکچر رو میتونیم بخونیم . در این بدنه ی شرط ، میخوام اطلاعات مربوط به نام فونت ای که کاربر انتخاب کرد (و به طبع باید رشته باشه) رو بخونم . خوب اگه دکمه ی کنسل رو بزنیم یا دکمه ی ok رو بزنیم ولی نام فونت ای رو انتخاب نکنیم ، مقدار قبلی یعنی مقداری که در خط

کد:
 Memory.SetStructureData(_LogFont, 14, 0, 0, "");    --FaceName
مشخص کردیم یعنی مقدار صفر رو میخونه

ولی اگه نام فونت ای رو مشخص کنیم ، مقادیر ثابت ای توی خروجی این خط کد

کد:
     fPtr = Memory.GetStructureData(_LogFont, 14, 0, "");  -- اطلاعات ذخيره شده در چهاردهمين استراکچر استراکچر _LogFont رو بگير
یعنی در متغییر fPtr ذخیره میشه . مثلا اگه Arial رو انتخاب کنیم ، همیشه مقدار ثابت 1634300481 ذخیره میشه . چون مقدار ثابت هه ، پس نباید اشاره گر باشه (من فکر میکردم ، رشته یعنی آرایه ای از کاراکترهاست ، پس باید اشارهگر باشه ولی مقدارش همیشه ثابت هه)
پس انگار باید مقدار باشه . از طرفی هم نوع اش ansi هست و هر کاراتر یک بایت ذخیره میشه پس برای رشته ی Arial که 5 کاراکتر هست ، باید 5 بایت اشغال بشه ولی عدد 1634300481 اگه تبدیل به باینری بشه ، عدد ۱۱۰۰۰۰۱۰۱۱۰۱۰۰۱۰۱۱۱۰۰۱۰۰۱۰۰۰۰۰۱ که هشت بایت هست !!

کلا اینکه چجوری میتونم مقدار رشته ای که کاربر از دیالوگ font انتخاب میکنه رو دریافت کنم؟
ساختار LOGFONT تون اشتباهه، اون TCHAR lfFaceName[LF_FACESIZE] یعنی 32 کاراکتر (که یکی اش صرف کاراکتر Null خواهد شد) نه اینکه بجایش یک اشاره گر قرار بدید. این یک آرایه با طول ثابته، در واقع این 32 کاراکتر جزء حافظه خود struct هستند، نه اینکه یک اشاره گر باشه به یک حافظه در جای دیگری. و اینکه کاراکتر بایت باشه یا دوبایتی بستگی به فراخوانی توابع داره که نسخه Ansi شون فراخوانی بشه یا Unicode شون. ChooseFontA نسخه Ansi ئه و ChooseFontW نسخه Unicode
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ساختار LOGFONT تون اشتباهه، اون TCHAR lfFaceName[LF_FACESIZE] یعنی 32 کاراکتر (که یکی اش صرف کاراکتر Null خواهد شد) نه اینکه بجایش یک اشاره گر قرار بدید. این یک آرایه با طول ثابته، در واقع این 32 کاراکتر جزء حافظه خود struct هستند، نه اینکه یک اشاره گر باشه به یک حافظه در جای دیگری. و اینکه کاراکتر بایت باشه یا دوبایتی بستگی به فراخوانی توابع داره که نسخه Ansi شون فراخوانی بشه یا Unicode شون. ChooseFontA نسخه Ansi ئه و ChooseFontW نسخه Unicode

ممنون استاد علی
ChooseFontA رو فراخونی کردم پس باید یک بایتی باشه
از کجا متوجه شدین که 32 بایت هست؟ پس یعنی رشته اش تا 31 اراکتر بیشتر جا نمیگیره؟ (آخریش باید null باشه)
خوب من اگه آرایه ای از char درست کنم و بهش بدم ، بازم اشاره گرش توش قرار میگیره
کلا بیشتر توضیح میدین؟
سئوال بعدی اینکه من وقتی با تابع MemoryEx.Allocate ، یه فضایی رو اختصاص میدم (مثلا 5 بایت اختصاص میدم) ، میتونم توش حتی بیشتر از 5 کاراتر بنویسم . یعنی موقع خوندن و نوشتن بیش از 5 بیت ، اشکالی نمیگیره . یعنی خودش اتوماتیک Realocate میکنه؟ پس اگه این طوره ، چرا باید حافظه ای اختصاص بدیم وقتی خودش مدیریت میکنه؟
 

the_king

مدیرکل انجمن
ممنون استاد علی
ChooseFontA رو فراخونی کردم پس باید یک بایتی باشه
از کجا متوجه شدین که 32 بایت هست؟ پس یعنی رشته اش تا 31 اراکتر بیشتر جا نمیگیره؟ (آخریش باید null باشه)
خوب من اگه آرایه ای از char درست کنم و بهش بدم ، بازم اشاره گرش توش قرار میگیره
کلا بیشتر توضیح میدین؟
سئوال بعدی اینکه من وقتی با تابع MemoryEx.Allocate ، یه فضایی رو اختصاص میدم (مثلا 5 بایت اختصاص میدم) ، میتونم توش حتی بیشتر از 5 کاراتر بنویسم . یعنی موقع خوندن و نوشتن بیش از 5 بیت ، اشکالی نمیگیره . یعنی خودش اتوماتیک Realocate میکنه؟ پس اگه این طوره ، چرا باید حافظه ای اختصاص بدیم وقتی خودش مدیریت میکنه؟
اون LF_FACESIZE یک مقدار ثابت از قبل تعریف شده در API ویندوز ئه با مقدار 32. API ویندوز پر از این مقادیر ثابت ئه، متغیر نیست. بله نهایتش 31 کاراکتر برای اسم جا دارید. قرار نیست توش اشاره گری قرار بدید، ممکنه از توابعی استفاده می کنید که دردسر ساز باشه ولی شما شروع آدرس اشاره گر رشته تون باید اشاره به اولین کاراکتر FaceName بکنه.
نه خودش Relocate نمی کنه، اصولا حافظه واحد تخصیصش بایت نیست، page ئه، مثلا 4096 بایت. البته ممکنه یک سیستم مدیریت جانبی حافظه این میون باشه که کار دیگه ای بکنه، من دارم در مورد خود سیستم مدیریت حافظه سیستم عامل ویندوز توضیح میدم. حالا یه اینترفیسی روی اندیس های حافظه کنترل داره و جلوی عبور از مرز درخواستی رو نمیده، یه اینترفیس دیگه کنترلی نداره و تا زمانی که از محدوده حافظه تخصیص داده خارج نشه و سیستم عامل جلوشو نگیره خطایی اعلام نمی کنه. اما اصولی نیست، چون اون حافظه اضافی در روتین ها کلا نادیده گرفته میشه. وقتی درخواست کپی کردن، با صفر پر کردن و ... رو بدید دیگه اون حافظه غیر درخواستی اضافی رو نادیده می گیره. برای سیستم عامل این مهمه که از محدوده حافظه تخصیص یافته به برنامه خارج نشید، دیگه اینکه تو اون حافظه اضافی چیکار میکنید برای سیستم عامل مهم نیست.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
استاد علی ، چند تا سئوال دارم
کد بسیار ساده هست
در کد زیر :


کد:
mem = Memory.Allocate(1024)
Memory.PutLong(mem, 65894)

الان 1024 بایت در حافظه ی mem قرار میگیره .
در خط دوم Long تعداد 4 بایت رو اشغال میکنه
الان حافظه ی mem که 1024 بایت هست ، فقط 4 بایت اش میمونه؟ یعنی حافظه ی mem بعد از اجرای خط دوم ، کم میشه؟ یا اینکه در حافظه ی mem فقط 4 بایت اش اشغال و بقیه ی بایت ها تا 1024 امین اش خالی میمونه؟

دومین سئوال اینکه اگه یه استراکچر بسازم ، در آرگومان اون استراکچر که مقدار رو میخواد ، بجای مقدار ، متغییر mem رو بهش بدم ، آدرس حافظه ی (اشاره گر) mem داخلش قرار میگیره یا صرفا مقدار mem که عددی به عنوان آدرس حافظه هست؟

سومین سئوال اینکه لزومی نداره که همه ی اعضای یه استراکچر ، حافظه هاشون کنار هم باشن دیگه درسته؟ یعنی در استراکچر LogFont ، اگه عضو FaceName ، خودش اشاره گر به یه خونه ی دیگه باشه ، مشکلی نداره دیگه؟ درسته؟
 

the_king

مدیرکل انجمن
سلام
استاد علی ، چند تا سئوال دارم
کد بسیار ساده هست
در کد زیر :


کد:
mem = Memory.Allocate(1024)
Memory.PutLong(mem, 65894)

الان 1024 بایت در حافظه ی mem قرار میگیره .
در خط دوم Long تعداد 4 بایت رو اشغال میکنه
الان حافظه ی mem که 1024 بایت هست ، فقط 4 بایت اش میمونه؟ یعنی حافظه ی mem بعد از اجرای خط دوم ، کم میشه؟ یا اینکه در حافظه ی mem فقط 4 بایت اش اشغال و بقیه ی بایت ها تا 1024 امین اش خالی میمونه؟
سوالاتی می کنین که نه به #C مربوطه و نه اتوپلی و نه ارتباط #C و اتوپلی. اینکه متد های یک پلاگین چه کاری انجام میده بر اساس مستندات پلاگینش مشخص میشه، اینکه دیگه ربطی به این تاپیک نداره.
یک پلاگین رو بکار می برید بدون اینکه مستنداتش رو مطالعه کنید، بعد میخواهید کسی دیگه ای بجاتون مستنداتش رو مطالعه کنه و جواب بده. دارم بر اساس اطلاعات صفحه Free Plugin : Memory Plugin جواب میدم. Mem صرفا یک آدرس حافظه است، طول حافظه تخصیص یافته هم با دستورات PutLong یا Put های مشابه عوض نمیشه، به قول شما بقیه اش خالی میمونه. شما در آدرسی که mem مشخص می کنه یک مقدار Long قرار می دهید، می توانید در mem + 4 یک Long دیگه قرار بدید و ...

دومین سئوال اینکه اگه یه استراکچر بسازم ، در آرگومان اون استراکچر که مقدار رو میخواد ، بجای مقدار ، متغییر mem رو بهش بدم ، آدرس حافظه ی (اشاره گر) mem داخلش قرار میگیره یا صرفا مقدار mem که عددی به عنوان آدرس حافظه هست؟
mem یک مقدار عددی ئه که آدرس یک حافظه است که احتمال داره آدرس مطلقی نباشه و بر اساس آدرس شروع حافظه پروسه اش باشه. ممکنه همینطوری به درد سایر پروسه ها نخوره.

سومین سئوال اینکه لزومی نداره که همه ی اعضای یه استراکچر ، حافظه هاشون کنار هم باشن دیگه درسته؟ یعنی در استراکچر LogFont ، اگه عضو FaceName ، خودش اشاره گر به یه خونه ی دیگه باشه ، مشکلی نداره دیگه؟ درسته؟
چرا خیلی مهمه که کنار هم باشند، یک بایت نباید اینور و اونور باشن. درضمن FaceName یک آرایه با طول ثابته و حافظه اش جزئی از خود ساختاره ئه، اشاره گر به یک حافظه دیگه نیست. شما اگه بخواهید بجاش اشاره گر قرار بدید طول حافظه ساختار رو کم کردید که اشتباهه. کلا ساختار struct رو باید همانطور که هست پیاده سازی کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سوالاتی می کنین که نه به #C مربوطه و نه اتوپلی و نه ارتباط #C و اتوپلی. اینکه متد های یک پلاگین چه کاری انجام میده بر اساس مستندات پلاگینش مشخص میشه، اینکه دیگه ربطی به این تاپیک نداره.
یک پلاگین رو بکار می برید بدون اینکه مستنداتش رو مطالعه کنید، بعد میخواهید کسی دیگه ای بجاتون مستنداتش رو مطالعه کنه و جواب بده. دارم بر اساس اطلاعات صفحه Free Plugin : Memory Plugin جواب میدم. Mem صرفا یک آدرس حافظه است، طول حافظه تخصیص یافته هم با دستورات PutLong یا Put های مشابه عوض نمیشه، به قول شما بقیه اش خالی میمونه. شما در آدرسی که mem مشخص می کنه یک مقدار Long قرار می دهید، می توانید در mem + 4 یک Long دیگه قرار بدید و ...


mem یک مقدار عددی ئه که آدرس یک حافظه است که احتمال داره آدرس مطلقی نباشه و بر اساس آدرس شروع حافظه پروسه اش باشه. ممکنه همینطوری به درد سایر پروسه ها نخوره.

ممنون استاد علی
بله ببخشید این سئوال ربط نداشت چندان . یه تاپیک دیگه بزنم؟
مستنداتش رو مطالعه کردم . میدونم mem آدرس حافظه هست . در مستنداتش نگفت که بقیه خالی میمونه یا نه که توضیح دادین
الان میتونم یه سئوال دیگه بپرسم؟
در کد زیر :


کد:
mem = Memory.Allocate(5);
Memory.PutString(mem, "Hi khobi?", -1, "Ascii");
Dialog.Message("", "Length of String in Memory : "..Memory.SizeString(mem).. "\nSize of Memory"..Memory.Size(mem));
Memory.Free(mem);

در خط اول ، 5 بایت خالی در حافظه فضا میگیره
در خط دوم ، میاد 9 کاراکتر رو به عنوان رشته در اون فضای گرفته شده ، مینویسه
سئوال اینجاست که رشته با هر نوع encode ای که باشه ، دیگه هر کاراکترش کمتر از 1 بایت فضا نمیگیره . ascii هم که میدونیم هر کاراکترش 1 بایت فضا میگیره . پس حداقل در خط دوم ، 9 بایت فضای خالی میخواد . پس چطوره که 5 بایت که براش گرفتیم ، توش راحت میتونه بنویسه و اروری هم نمیده؟!!

چرا خیلی مهمه که کنار هم باشند، یک بایت نباید اینور و اونور باشن. درضمن FaceName یک آرایه با طول ثابته و حافظه اش جزئی از خود ساختاره ئه، اشاره گر به یک حافظه دیگه نیست. شما اگه بخواهید بجاش اشاره گر قرار بدید طول حافظه ساختار رو کم کردید که اشتباهه. کلا ساختار struct رو باید همانطور که هست پیاده سازی کنید.

آها ممنون
پس با این حال ، انگار نمیشه با این پلاگین ها ، کدی برای کار کردن با فونت در api نوشت؟
چون نمیشه یه استراکچری از نوع رشته ایجاد کرد چه برسه به اینکه طول رشته رو براش مشخص کنیم (البته توی مستنداتش میگه شاید بشه اما ممکنه مشکل بوجود بیاد) . توی مستنداتش هم میگه برای ساخت رشته ، اول یه حافظه alloc کنید (که با این کار ، حافظه ای جدای از حافظه ی استراکچرمون بهش اختصاص داده میشه و طبق توضیحات تون نمیشه این کار رو کرد) و بعد اشاره گرش رو به استراکچر بدیم
 

the_king

مدیرکل انجمن
ممنون استاد علی
بله ببخشید این سئوال ربط نداشت چندان . یه تاپیک دیگه بزنم؟

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

در آدرس mem فلان مقدار رو قرار میده، اگر طول حافظه تخصیص یافته رو کم یا زیاد می کرد که حتما به این موضوع اشاره میشد.

الان میتونم یه سئوال دیگه بپرسم؟
در کد زیر :


کد:
mem = Memory.Allocate(5);
Memory.PutString(mem, "Hi khobi?", -1, "Ascii");
Dialog.Message("", "Length of String in Memory : "..Memory.SizeString(mem).. "\nSize of Memory"..Memory.Size(mem));
Memory.Free(mem);

در خط اول ، 5 بایت خالی در حافظه فضا میگیره
در خط دوم ، میاد 9 کاراکتر رو به عنوان رشته در اون فضای گرفته شده ، مینویسه
سئوال اینجاست که رشته با هر نوع encode ای که باشه ، دیگه هر کاراکترش کمتر از 1 بایت فضا نمیگیره . ascii هم که میدونیم هر کاراکترش 1 بایت فضا میگیره . پس حداقل در خط دوم ، 9 بایت فضای خالی میخواد . پس چطوره که 5 بایت که براش گرفتیم ، توش راحت میتونه بنویسه و اروری هم نمیده؟!!

قبلا هم همچین سوالی رو پرسیدین، سیستم عامل حافظه رو برحسب page تخصیص میده، نه بایت. مثل اینه که به سوپری محل بگید یک قاشق ماست بده، ماست رو سطلی میفروشه، حتی اگه یک قاشق ماست لازم دارید بهتون یک سطل کامل ماست میده. سیستم عامل اصلا براش متغیر های پروسه معنی نداره. نمیفهمه تو page چند تا متغیر هست. به هیچ پروسه ای هم یک چهارم page تخصیص نمیده، یک بایت ازش بخواهید یک page کامل تخصیص میده، برایش هم مهم نیست که با حافظه بلا استفاده page چکار می کنید، اگه حافظه درخواستی یک بایت هم از یک page بیشتر بشه دو تا page تخصیص میده. حالا شما ازش 5 بایت خواستید بهتون یک page داده. هیچ تضمینی وجود نداره که فراتر از اون 5 بایت به مورد دیگه ای در همون پروسه حافظه اختصاص داده نشده باشه، یعنی اگه هر بخشی از اون پروسه درخواست حافظه بکنه، سیستم عامل از بخش بلا استفاده همون page بهش آدرس میده، برای همین شما ممکنه ادامه اون string رو روی حافظه متغیر دیگری نوشته باشید، سیستم عامل روی این مساله هیچ کنترلی نداره، این تداخل مسئولیتش با خود زبان و کامپایلر و مفسرش ئه، در خیلی از زبان ها این مورد اصلا چک نمیشه که دارید از محدوده حافظه تخصیص یافته خارج میشید. برای همین ممکنه پروسه Crash کنه. این کار شما الان ایراد داره. پروسه رو از حالت پایدار و با نتایج تضمین شده خارج می کنه. ممکنه پروسه یکبار درست کار کنه، یکبار کرش کنه و یکبار محاسبات اشتباه انجام بده. یعنی نتایج قابل پیش بینی نیست. این مساله که خطا نمیده خیلی عادیه. فقط یک تعداد معدودی کامپایلر ها و مفسر ها همچین موردی رو چک می کنند. از نظر سیستم عامل اینها خطا نیست. سیستم عامل فقط میگه از محدوده page هایی که به پروسه تخصیص دادم خارج نشو، داخل page خودش هر کاری بکنه ربطی به سیستم عامل نداره.


آها ممنون
پس با این حا ال ، انگار نمیشه با این پلاگین ها ، کدی برای کار کردن با فونت در api نوشت؟
چون نمیشه یه استراکچری از نوع رشته ایجاد کرد چه برسه به اینکه طول رشته رو براش مشخص کنیم (البته توی مستنداتش میگه شاید بشه اما ممکنه مشکل بوجود بیاد) . توی مستنداتش هم میگه برای ساخت رشته ، اول یه حافظه alloc کنید (که با این کار ، حافظه ای جدای از حافظه ی استراکچرمون بهش اختصاص داده میشه و طبق توضیحات تون نمیشه این کار رو کرد) و بعد اشاره گرش رو به استراکچر بدیم
تا اونجا که به API مربوطه فرقی نمی کنه که محتویات struct چند تا فیلد یا از چه نوعی باشه، API ازتون یک حافظه با طول مشخص و محتویات باینری مشخص میگیره و همونطور هم تحویل میده. یعنی شما اگه در struct بجای یک رشته با طول ثابت فرضا چهار کاراکتر ANSI، بیایید چهار تا فیلد یک بایتی هم بذارید یا یک LONG بذارید یا دو تا WORD بذارید طول حافظه struct درسته و برای API فرقی بین اینها نیست، اما اینکه میاییم فیلد های داخل struct رو یکی یکی تعریف می کنیم، برای ساده کردن مقدار دهی شونه.و طبیعتا پر کردن یک حافظه که فقط بایت توشه خیلی سخت تر از حالتیه که فیلد ها بر حسب نوع داده مناسب شون تفکیک شدن. منظورم اینه که از نظر فنی میشه یک struct رو فقط یک آرایه از بایت در نظر گرفت به شرطی که بایت ها با ترتیب و موقعیت درست و با مقدار مناسب پر بشن. API که نمیفهمه شما اون حافظه رو با چه روش و ترفندی پر می کنید، فقط آدرس شروع حافظه اش رو ازتون گرفته. این تعاریف فیلد ها برای استفاده داخل زبان شما است و برای ساده تر مقدار خوندن و مقدار نوشتن در ساختار حافظه. همانطور که در #C میاییم محتویات struct رو در یک حافظه Allocate شده کپی می کنیم و اون حافظه رو به متد خارجی می فرستیم، نه اون حافظه Managed ئه struct رو، یعنی داریم یک حافظه بایتی رو می فرستیم، دیگه فیلدها داخلش تفکیک شده نیستن.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
قطعا تاپیک مجزایی لازم داره ولی من شخصا تسلطی به پلاگین هایی که استفاده می کنید ندارم که بخوام در موردشون راهنمایی کنم.

در آدرس mem فلان مقدار رو قرار میده، اگر طول حافظه تخصیص یافته رو کم یا زیاد می کرد که حتما به این موضوع اشاره میشد.


قبلا هم همچین سوالی رو پرسیدین، سیستم عامل حافظه رو برحسب page تخصیص میده، نه بایت. مثل اینه که به سوپری محل بگید یک قاشق ماست بده، ماست رو سطلی میفروشه، حتی اگه یک قاشق ماست لازم دارید بهتون یک سطل کامل ماست میده. سیستم عامل اصلا براش متغیر های پروسه معنی نداره. نمیفهمه تو page چند تا متغیر هست. به هیچ پروسه ای هم یک چهارم page تخصیص نمیده، یک بایت ازش بخواهید یک page کامل تخصیص میده، برایش هم مهم نیست که با حافظه بلا استفاده page چکار می کنید، اگه حافظه درخواستی یک بایت هم از یک page بیشتر بشه دو تا page تخصیص میده. حالا شما ازش 5 بایت خواستید بهتون یک page داده. هیچ تضمینی وجود نداره که فراتر از اون 5 بایت به مورد دیگه ای در همون پروسه حافظه اختصاص داده نشده باشه، یعنی اگه هر بخشی از اون پروسه درخواست حافظه بکنه، سیستم عامل از بخش بلا استفاده همون page بهش آدرس میده، برای همین شما ممکنه ادامه اون string رو روی حافظه متغیر دیگری نوشته باشید، سیستم عامل روی این مساله هیچ کنترلی نداره، این تداخل مسئولیتش با خود زبان و کامپایلر و مفسرش ئه، در خیلی از زبان ها این مورد اصلا چک نمیشه که دارید از محدوده حافظه تخصیص یافته خارج میشید. برای همین ممکنه پروسه Crash کنه. این کار شما الان ایراد داره. پروسه رو از حالت پایدار و با نتایج تضمین شده خارج می کنه. ممکنه پروسه یکبار درست کار کنه، یکبار کرش کنه و یکبار محاسبات اشتباه انجام بده. یعنی نتایج قابل پیش بینی نیست. این مساله که خطا نمیده خیلی عادیه. فقط یک تعداد معدودی کامپایلر ها و مفسر ها همچین موردی رو چک می کنند. از نظر سیستم عامل اینها خطا نیست. سیستم عامل فقط میگه از محدوده page هایی که به پروسه تخصیص دادم خارج نشو، داخل page خودش هر کاری بکنه ربطی به سیستم عامل نداره.
ممنون استاد علی
page چیه؟


تا اونجا که به API مربوطه فرقی نمی کنه که محتویات struct چند تا فیلد یا از چه نوعی باشه، API ازتون یک حافظه با طول مشخص و محتویات باینری مشخص میگیره و همونطور هم تحویل میده. یعنی شما اگه در struct بجای یک رشته با طول ثابت فرضا چهار کاراکتر ANSI، بیایید چهار تا فیلد یک بایتی هم بذارید یا یک LONG بذارید یا دو تا WORD بذارید طول حافظه struct درسته و برای API فرقی بین اینها نیست، اما اینکه میاییم فیلد های داخل struct رو یکی یکی تعریف می کنیم، برای ساده کردن مقدار دهی شونه.و طبیعتا پر کردن یک حافظه که فقط بایت توشه خیلی سخت تر از حالتیه که فیلد ها بر حسب نوع داده مناسب شون تفکیک شدن. منظورم اینه که از نظر فنی میشه یک struct رو فقط یک آرایه از بایت در نظر گرفت به شرطی که بایت ها با ترتیب و موقعیت درست و با مقدار مناسب پر بشن. API که نمیفهمه شما اون حافظه رو با چه روش و ترفندی پر می کنید، فقط آدرس شروع حافظه اش رو ازتون گرفته. این تعاریف فیلد ها برای استفاده داخل زبان شما است و برای ساده تر مقدار خوندن و مقدار نوشتن در ساختار حافظه. همانطور که در #C میاییم محتویات struct رو در یک حافظه Allocate شده کپی می کنیم و اون حافظه رو به متد خارجی می فرستیم، نه اون حافظه Managed ئه struct رو، یعنی داریم یک حافظه بایتی رو می فرستیم، دیگه فیلدها داخلش تفکیک شده نیستن.
آها ممنون
منظورتون اینه که بجای string ، میشه 32 بایت (چون اون فیلد ، 32 بیت خونه حتما لازم داشت دیگه) خونه رو به هر روش اشغال کرد (مثلا 8 تا long رو اشغال کرد و یا یه آرایه ای که کلا 32 بایت اشغال کنه رو درست کرد و...) و بعد مقداردهی کرد خونه ها رو و بعد آدرساولین خونه از این 32 بایت رو داد؟
حالا مقداردهی اش رو چی کار باید کرد؟ چون long فقط عدد قبول میکنه . باید کد اسکی شونو داد؟
 

the_king

مدیرکل انجمن
ممنون استاد علی
page چیه؟

واحد حافظه است. مثلا 4 کیلوبایت یا حتی چند مگابایت. حافظه برای اینکه آدرس بندی بشه و شماره آدرس بهشون تخصیص داده بشه باید تقسیم بشه به واحدی بزرگتر از بایت تا بشه مدیریت شون کرد. بایت برای مدیریت زیادی واحد کوچیکیه و بررسی اینکه تخصیص داده شده یا نشده و به کی تخصیص داده شده و معیوب هست یا نیست و دسترسی اش چه تنظیمی داره و ... سربار خیلی زیادی خواهد داشت و منابع سیستم بیخود واسه مدیریتش هدر میره.
Page (computer memory) - Wikipedia
شنیدین که میگن هارد دیسک بد سکتور داره؟ صحبت بایت نمی کنن، میگن سکتور. نمیگن یه بایت بد داره، کل یک سکتور خراب از رده خارج میشه که معمولا هر سکتور معادل 512 بایته. حالا اگه از سیستم فایل درخواست کنید که به من یک بایت یا حتی یک سکتور فضا روی دیسک بده، بهتون یک کلاستر میده که ممکنه خودش چندین سکتور باشه. بهتون یک واحد بزرگی به نام کلاستر میده، چون تعداد سکتور ها اونقدر زیاده که آدرس بندی و مدیریت شون مشکل میشه و کارایی میاد پایین. حافظه RAM و حافظه مجازی هم همینطوره، مدیریت تک تک بایت ها که کدوم به کدوم پروسه تعلق دارند سخت و کند میشه، از واحد بزرگتری استفاده می کنند به نام Page

آها ممنون
منظورتون اینه که بجای string ، میشه 32 بایت (چون اون فیلد ، 32 بیت خونه حتما لازم داشت دیگه) خونه رو به هر روش اشغال کرد (مثلا 8 تا long رو اشغال کرد و یا یه آرایه ای که کلا 32 بایت اشغال کنه رو درست کرد و...) و بعد مقداردهی کرد خونه ها رو و بعد آدرساولین خونه از این 32 بایت رو داد؟
حالا مقداردهی اش رو چی کار باید کرد؟ چون long فقط عدد قبول میکنه . باید کد اسکی شونو داد؟
بله. باید فرضا اگه long باشه باید مقدار چهار کاراکتر رو با ترتیب درست و بصورت یک مقدار 32 بیتی ترکیب شده داخلش قرار بدید. برای همین سختیشه که struct تعریف میشه دیگه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
واحد حافظه است. مثلا 4 کیلوبایت یا حتی چند مگابایت. حافظه برای اینکه آدرس بندی بشه و شماره آدرس بهشون تخصیص داده بشه باید تقسیم بشه به واحدی بزرگتر از بایت تا بشه مدیریت شون کرد. بایت برای مدیریت زیادی واحد کوچیکیه و بررسی اینکه تخصیص داده شده یا نشده و به کی تخصیص داده شده و معیوب هست یا نیست و دسترسی اش چه تنظیمی داره و ... سربار خیلی زیادی خواهد داشت و منابع سیستم بیخود واسه مدیریتش هدر میره.
Page (computer memory) - Wikipedia
شنیدین که میگن هارد دیسک بد سکتور داره؟ صحبت بایت نمی کنن، میگن سکتور. نمیگن یه بایت بد داره، کل یک سکتور خراب از رده خارج میشه که معمولا هر سکتور معادل 512 بایته. حالا اگه از سیستم فایل درخواست کنید که به من یک بایت یا حتی یک سکتور فضا روی دیسک بده، بهتون یک کلاستر میده که ممکنه خودش چندین سکتور باشه. بهتون یک واحد بزرگی به نام کلاستر میده، چون تعداد سکتور ها اونقدر زیاده که آدرس بندی و مدیریت شون مشکل میشه و کارایی میاد پایین. حافظه RAM و حافظه مجازی هم همینطوره، مدیریت تک تک بایت ها که کدوم به کدوم پروسه تعلق دارند سخت و کند میشه، از واحد بزرگتری استفاده می کنند به نام Page

خیلی ممنون استاد علی.
بخاطر همینه که مثلا فلش 16 گیگ میخریم اما عملا 15 گیگ میشه؟ یا مثلا هارد هم همینطور و به اندازه ی واقعی خودشون نیستن؟

-----------------------------------------------------------------------

میگم اگه توی اتوپلی (که از زبان لوا استفاده میکنه) ، یه تابع تعریف کنیم (مثلا تابع زیر که یه رشته دریافت و توی MessageBox نمایش میده و یه عدد را برمیگردونه) :


کد:
function MyFunction(myStringPar)
myInt = 100;
Dialog.Message("Notice", myStringPar, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
return myInt;
end

هر چند تابع Dialog.Message در بالا در اتوپلی تعریف شد ، اما توی خودش همون تابع MessageBox در api ویندوز را فراخونی میکنه .
حالا سئوالم اینه که اگه اشاره گر به این تابع (اشاره گر به تابع MyFunction) را به یه زبان دیگه بفرستیم (مثلا به زبان سی شارپ ای که اون زبان سی شارپ در دل خودش توسط wrapper ، از زبان لوا استفاده کنه و درون اون زبان لوا ، توسط اشاره گر به این تابع ، این متد MyFunction را اجرا کنیم) ، در این صورت ، تابع Dialog.Message (که داخل متد MyFunction فراخونی شده) واین تابع ی Dialog.Message در اون زبان لوا که در سی شارپ هست ، تعریف نشده هم بدون مشکل اجرا میشه؟ یا موقع اجرای متد Dialog.Message که در اتوپلی فقط تعریف شد ، ارور میده؟
ممنون
 

the_king

مدیرکل انجمن
خیلی ممنون استاد علی.
بخاطر همینه که مثلا فلش 16 گیگ میخریم اما عملا 15 گیگ میشه؟ یا مثلا هارد هم همینطور و به اندازه ی واقعی خودشون نیستن؟

نه، اون دلیلش دو مورد ئه، تفاوت مقدار دو واحد همنام و فضای لازم برای فرمت بندی. که البته موضوعش هم ربطی به این تاپیک نداره.

میگم اگه توی اتوپلی (که از زبان لوا استفاده میکنه) ، یه تابع تعریف کنیم (مثلا تابع زیر که یه رشته دریافت و توی MessageBox نمایش میده و یه عدد را برمیگردونه) :
کد:
function MyFunction(myStringPar)
myInt = 100;
Dialog.Message("Notice", myStringPar, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
return myInt;
end

هر چند تابع Dialog.Message در بالا در اتوپلی تعریف شد ، اما توی خودش همون تابع MessageBox در api ویندوز را فراخونی میکنه .
حالا سئوالم اینه که اگه اشاره گر به این تابع (اشاره گر به تابع MyFunction) را به یه زبان دیگه بفرستیم (مثلا به زبان سی شارپ ای که اون زبان سی شارپ در دل خودش توسط wrapper ، از زبان لوا استفاده کنه و درون اون زبان لوا ، توسط اشاره گر به این تابع ، این متد MyFunction را اجرا کنیم) ، در این صورت ، تابع Dialog.Message (که داخل متد MyFunction فراخونی شده) واین تابع ی Dialog.Message در اون زبان لوا که در سی شارپ هست ، تعریف نشده هم بدون مشکل اجرا میشه؟ یا موقع اجرای متد Dialog.Message که در اتوپلی فقط تعریف شد ، ارور میده؟
ممنون
قاعدتا Error میده چون مفسرش متفاوته، درسته که هر دو مفسر زبان یکسانی هستند اما پیاده سازی متفاوت و ناسازگاری دارند. همونطور که در کامپایلر های ++C شرکت Borland یک دستور ()clrscr وجود داشت که جزو توابع کتابخانه های استاندارد ++C نیست و در کامپایلر های دیگه ++C کد با خطا متوقف میشد.
 

جدیدترین ارسال ها

بالا