PDA

View Full Version : بدست اوردن ادرس یک تابع که در یکی از کلاس های برنامه تعریف شده



taze kar
شنبه 12 شهریور 1384, 14:30 عصر
با سلام

وقتی یک DLL رو لود میکنم در مورد بدست اوردن توابع اکسپورت شده از اون هیچ مشکلی ندارم و لی توابعی که داخل برنامه ساختم نمی تونم ادرسشون رو بدست بیارم .
اول هندل برنامه ام رو پیدا میکنم و بعد وقتی با تابع GetProcAddress میخوام که ادرس یکی از تابع ها رو پیدا کنم فقط و فقط NULL در یافت می کنم .
پیشا پیش ممنون .

sasan_vm
شنبه 12 شهریور 1384, 14:40 عصر
سلام
دوست عزیز GetProcAddress فقط برای بدست اوردن ادرس توابع dll است نه ادرس
توابع یک application .

:لبخندساده

Reza_K
شنبه 12 شهریور 1384, 15:21 عصر
سلام
دوست عزیز GetProcAddress فقط برای بدست اوردن ادرس توابع dll است نه ادرس
توابع یک application .

:لبخندساده

تابع GetProcAddress تنها آدرس توابع موجود در Export Section یک Dll یا Exe رو بر می‌گردونه. حالا برای بدست آوردن آدرس تابعی که خودتان در ماجول جاری کد کرده اید چکار باید کرد؟

از نام آن تابع بدون پرانتز استفاده کنید(در CPP قضیه اندکی متفاوت است).

sh_roohani
شنبه 12 شهریور 1384, 17:14 عصر
سلام تازه جان،
با Function Pointers گوگل کن به نکات جالبی بر می خوری از جمله یکی دو تا مقاله کامل و جامع در باره اشاره گر به تابع هم در C و هم در ++C.
باور کن من بخیل نیستم، لینکش یادم رفته، والا همین الان واست می ذاشتمش اینجا :لبخند:

taze kar
شنبه 12 شهریور 1384, 19:27 عصر
سلام تازه جان،
با Function Pointers گوگل کن به نکات جالبی بر می خوری از جمله یکی دو تا مقاله کامل و جامع در باره اشاره گر به تابع هم در C و هم در ++C.
باور کن من بخیل نیستم، لینکش یادم رفته، والا همین الان واست می ذاشتمش اینجا :لبخند:
این حرفها چیه روحی جون . ما مخلصت هم هستیم . هر سوالی که تا حالا پرسیدم شرمندم کردی .

از راهناییت هم ممنون . (........................این هوا)

taze kar
شنبه 12 شهریور 1384, 19:37 عصر
راستی قضیه این call bach و WinApiEntry چیه ؟

sh_roohani
شنبه 12 شهریور 1384, 19:48 عصر
چاکرتیم،
CALLBACK و WINAPI هر دو calling convention هستند. هر دو هم همون stdcall__ هستند. به خصوص CALLBACK رو برای نوشتن توابع callback در ویندوز به کار می برن. مثلا برای نوشتن تابعی که EnumChildWindows هر بار که به یه child می رسه اونو صدا می کنه.

taze kar
یک شنبه 13 شهریور 1384, 09:51 صبح
اصلا" نگرفتم ............میشه از اون اول اولش بگی ؟ (ممنون)

sh_roohani
یک شنبه 13 شهریور 1384, 10:49 صبح
ببین قربون شکلت، بعضی وقتا لازمه یه تابع، یه تابع دیگه رو از طریق آدرسش صدا بزنه. چرا؟ چون که وقتی تابع اول رو می نویسیم، هنوز نمی دونیم داخل تابع دوم چه خبره. مثلا، شما فرض کن یه تابعی نوشتی که سعی می کنه تک تک پورتهای سریال روی کامپیوتر رو باز کنه تا ببینه که کدوم در دسترسه، و می خوای که هر پورتی که تست می شه، مطلع بشی. یه راهش اینه که بگی هر پورت که تست شد یه پیغام به یه پنجره خاص بفرسته، اما اگه برنامه ت کنسولی بود چی؟ بنابراین وقتی تابع شمارنده رو می نویسی، یه پارامتر اون رو به اشاره گر به یه تابع با یه prototype مشخص در نظر می گیری. مثلا پارامتر اول تابع beginthread_ از نوع زیر هست:

void( __cdecl *start_address )( void * )
یعنی تابعی که مقدار برگشتی اون void و پارامتر اون *void می باشد. البته beginthread_ که می دونی تابع شمارنده نیست، فقط به عنوان یه مثال آوردم. حالا تو ویندوز یه سری از توابع (به ویژه توابع شمارنده) هستن که با هر بار شمارش یه تابع دیگه رو از روی اشاره گرش صدا می زنن تا اون تابع با اون مورد شمارش شده (در اینجا پنجره فرزند شمارش شده) هر کاری که صلاح می دونه انجام بده. Calling convention این نوع از توابع رو CALLBACK در نظر می گیرن.
Prototype تابع EnumChildWindows به صورت زیره:

BOOL EnumChildWindows(
HWND hWndParent, // handle to parent window
WNDENUMPROC lpEnumFunc, // callback function
LPARAM lParam // application-defined value
);

و تابع CALLBACK اون:

BOOL CALLBACK EnumChildProc(
HWND hwnd, // handle to child window
LPARAM lParam // application-defined value
);
بازم اگه سوالی هست در خدمتیم.


با تشکر از MSDN

Inprise
یک شنبه 13 شهریور 1384, 12:40 عصر
برای بدست آوردن آدرس یا اشاره گری به تابع مورد نظر تو فایل Exe ات میتونی از Loadlibrary استفاده کنی ؛ کافیه هنگام تعریف تابع ات از قاعدهء dllexport تبعیت کنه و آدرسی که به Loadlibrary پاس میکنی دقیقا مشابه آدرس فایل اجرائی در حال اجرا نباشه ؛ مثلا" برای فایل اجرائ ات یک نام طولانی انتخاب کن ، بعد با استفاده از قواعد نام گذاری داس ، نام کوتاه شدهء فایل اجرائیت رو به عنوان پارامتر به Loadlibrary پاس کن ، Loader سیستم عامل یک نسخه دیگه از فایلت رو وارد حافظه میکنه و هندل تابع مذکور رو برمیگردونه ، درست مثل وقتی که از DLL ها استفاده میکنی ، در عمل این دو فرقی هم با هم ندارند .

موفق باشی

Blaster
یک شنبه 13 شهریور 1384, 17:53 عصر
taze kar جان بزار یکمی ساده تر بگم . اصولا توابع CALLBACK ، توابعی هستند که توسط برنامه نویس نوشته می شن ولی این Windows هست که اونها رو
فراخوانی می کنه . نوع این توابع و تعداد پارامترهای اونها از قبل مشخص شده و برنامه نویس باید بدنه اون تابع ها رو پر کنه و در نهایت ادرس اونها رو به محل مورد نظر ارسال کنه.

taze kar
دوشنبه 14 شهریور 1384, 14:08 عصر
با تشکر از این که وقت گذاشتید و سوالاتم رو جواب دادید .
توی یک برنامه کونسول بدون دردسر با استفاده از نام یک تابع ادرسش رو بدست می ارم و هیچ مشکلی هم نیست ولی وقتی با ادرس توابع بک کلاس کار میکنم هنگام کامپایل این ارور رو میده :
error C2440: '=' : cannot convert from 'void (__thiscall MyClass::* )(void)' to 'ّFuncPointer'

مثلا" این کد :


void MyClass::Func1(void)
{
MessageBox(NULL,"fuvction1","",0);
return ;
} ;
void MyClass::Func2(void)
{
typedef void(*FuncPointer)(void);
FuncPointer fp ;
fp = Func1 ;
fp();
return ;
};

که هنگام کامپایل قات میزنه .
اقای ابنپرایز من درست متوجه نشدم . منظورتون از " تبعیت از قاعده dllexport " رو اصلا نگرفتم . میشه یه نمه توضیح در این مورد بدین .. اخه تا حالا هر چی DLL نوشتم یه فایل با پسوند DEF توی پروژه میساختم و......... باقیه ما جرا رو دیگه میدونید . ولی چیزی ار قاعده dllexport نشنیده بودم . با تشکر .

و یه چیز دیگه این که لطفا" یک کتاب خوب معرفی کنید . چون دوست دارم ماهی گیری رو یاد بگیرم و نه ماهی گرفتن از یکی دیگه رو .
باز هم ممنون از لطفتون . و امیدوارم زیاد خواهی منو ببخشید

sh_roohani
دوشنبه 14 شهریور 1384, 19:43 عصر
سلام تازه جان،
به نظرم این شیوه تعریف اشاره گر به تابع، در مورد توابع عضو کلاس کار نمی کنه، مگر اینکه استاتیک باشن که اونم می دونی محدودیتهای خاص خودشو داره. فکر کنم من یه وقتی درباره اشاره گر به توابع عضو یه مطلبی پیدا کرده بودم، ولی هیچوقت فرصت خوندنشو نداشتم :لبخند: .
حالا این توفیقی شد که امشب برم خونه، اگه پیداش کردم بخونمش. آخه می دونی تو هارد کامپیوتر من شتر با بارش گم می شه :افسرده: .

Inprise
سه شنبه 15 شهریور 1384, 12:54 عصر
- dllexport رو توی MSDN جستجو کن ؛ کافیه فقط تابع ات رو dllexport کنی تا بتونی حتی وقتی توی یک exe پیاده سازی شده با استفاده از Loadlibrary هندلش رو بدست بیاری .

- برای ایجاد اشاره گر به توابع عضو یک کلاس :



#include <iostream.h>

class A {
public:
void f(int i) {cout << "value is: " << i << "\n";}
};

typedef void (A::*pmfA)(int);

pmfA x = &A::f;

void main()
{
A a;
A* p = &a;

(p->*x)(37);
}

sh_roohani
سه شنبه 15 شهریور 1384, 13:09 عصر
ممنون از Inprise، چون من هم خیلی علاقه داشتم اینو بدونم. :تشویق:

taze kar
چهارشنبه 16 شهریور 1384, 10:52 صبح
با تشکر از همگی که لطف کردین وقت گذاشتین و جواب دادین .
ولی من هنوز قضیه این call back رو درست متوجه نشدم.

taze kar جان بزار یکمی ساده تر بگم . اصولا توابع CALLBACK ، توابعی هستند که توسط برنامه نویس نوشته می شن ولی این Windows هست که اونها رو
فراخوانی می کنه . نوع این توابع و تعداد پارامترهای اونها از قبل مشخص شده و برنامه نویس باید بدنه اون تابع ها رو پر کنه و در نهایت ادرس اونها رو به محل مورد نظر ارسال کنه.

منظور از محل مورد نظر چیه ؟
با تشکر مجدد . (دیگه کم کم دارم پر رو میشم .)

taze kar
چهارشنبه 16 شهریور 1384, 10:54 صبح
راستی یادم رفت یه منبع توپ هم معرفی کنید . (خیلی مخلصیم )Please

sh_roohani
چهارشنبه 16 شهریور 1384, 11:52 صبح
تازه جان،
محل مورد نظر یعنی همون تابعی که قراره تابع callback شما رو فراخوانی کنه.

Blaster
چهارشنبه 16 شهریور 1384, 16:29 عصر
منظورم همون بود!

Reza_K
چهارشنبه 16 شهریور 1384, 18:40 عصر
با تشکر از این که وقت گذاشتید و سوالاتم رو جواب دادید .
توی یک برنامه کونسول بدون دردسر با استفاده از نام یک تابع ادرسش رو بدست می ارم و هیچ مشکلی هم نیست ولی وقتی با ادرس توابع بک کلاس کار میکنم هنگام کامپایل این ارور رو میده :
error C2440: '=' : cannot convert from 'void (__thiscall MyClass::* )(void)' to 'ّFuncPointer'

مثلا" این کد :


void MyClass::Func1(void)
{
MessageBox(NULL,"fuvction1","",0);
return ;
} ;
void MyClass::Func2(void)
{
typedef void(*FuncPointer)(void);
FuncPointer fp ;
fp = Func1 ;
fp();
return ;
};

که هنگام کامپایل قات میزنه .
اقای ابنپرایز من درست متوجه نشدم . منظورتون از " تبعیت از قاعده dllexport " رو اصلا نگرفتم . میشه یه نمه توضیح در این مورد بدین .. اخه تا حالا هر چی DLL نوشتم یه فایل با پسوند DEF توی پروژه میساختم و......... باقیه ما جرا رو دیگه میدونید . ولی چیزی ار قاعده dllexport نشنیده بودم . با تشکر .

و یه چیز دیگه این که لطفا" یک کتاب خوب معرفی کنید . چون دوست دارم ماهی گیری رو یاد بگیرم و نه ماهی گرفتن از یکی دیگه رو .
باز هم ممنون از لطفتون . و امیدوارم زیاد خواهی منو ببخشید

دوست عزیر تابعی که شما قصد بدست آوردن آدرش را دارید یک عضو کلاس است. در واقع این تابع از نوع Cpp میباشد. اینگونه توابع دارای خصوصیات متفاوتی از جمله پارامتر this( که از طریق رجیستر EDX به تابع ارسال میشود) میباشد. در کد فوق باید امضای مناسبی را ارئه کنید تا امکان انتساب آدرس تابع برای شما ممکن شود.
جهت تکمیل مطلب، در Cpp مانند C با آدرس توابع کار نمیکنند بلکه آدرس ابجکت ها و Interface ها مورد توجه اند. کافیست به نحوه پیاده سازی delegate ها در DOT NET دقت کنید. یک delegate کلاسی است که متدی بنام invoke دارد. این کلاس و متد invoke با هم مانند یک function pointer عمل می کنند.

در صورتی که باز هم تمایل به استفاده از FP ها در CPP را دارید به آدرس زیر مراجعه کنید.

www.function-pointer.org

taze kar
شنبه 19 شهریور 1384, 08:36 صبح
با سلام مجدد .
ببینید من درست قضه رو گرفتم یا نه . یه تابع Callback رو ویندوز فراخوانی می کنه برای کار خاصی و ما فقط به ویندوز اعلام می کنیم که این تابع کجا هست . مثلا زمانی که یک کلاس پنجره رو رجیستر می کنیم به تابع CallBack داره که همه بیغام های پنجره رو می تونیم توش بسته به شرایط کار های خودمون رو انجام بدیم و این تابع رو ویندوز فرا خوانی می کنه و نه برنامه ما . درست گفتم ؟
ممنون

sh_roohani
شنبه 19 شهریور 1384, 10:43 صبح
همینه که گفتی، فقط جهت یادآوری بگم که علاوه بر این که سیستم عامل می تونه یه تابع رو از طریق اشاره گر به اون تابع صدا بزنه، خود شما هم (همونطور که تا حالا دیگه حتما دیدی)، می تونی اینکار رو بکنی.

Inprise
شنبه 19 شهریور 1384, 11:59 صبح
تا وقتی تابع Callback تو فضای آدرسی پروسه خودت قرار گرفته شده باشه ، این فقط برنامهء خودته که اونو رو فراخوانی میکنه ؛ ویندوز موجودیت مشخصی نیست که بتونی اجرای یک تابع رو بهش نسبت بدی ؛ برنامهء تو طب منطق و روند مورد نظرش ، آدرس آفست شروع تابع رو به کنترل پردازنده بر میگردونه ... ؛ هنگام شروع برنامه تنها لطفی که ویندوز در حقت میکنه ارتباط با مدیر حافظه مجازی و اختصاص حافظه و منابع لازم و فراخوانی توابع سیستمی به فضای آدرسی پروسه ات است ، و تا وقتی توابع یا منابع ، تو فضای آدرسی پروسه ات تعریف شده باشند - همراه با استثنائاتی - این فقط برنامهء تو است که میتونه از اونها استفاده کنه .

taze kar
شنبه 19 شهریور 1384, 13:59 عصر
تا وقتی تابع Callback تو فضای آدرسی پروسه خودت قرار گرفته شده باشه ، این فقط برنامهء خودته که اونو رو فراخوانی میکنه ؛ ، و تا وقتی توابع یا منابع ، تو فضای آدرسی پروسه ات تعریف شده باشند - همراه با استثنائاتی - این فقط برنامهء تو است که میتونه از اونها استفاده کنه .

پس این وسط قضیه Injection چی میشه ؟ اگر به نهوی کدمون رو به یه پروسه دیگه وارد کنیم اون وقت کنترلش از دستمون خارج میشه ؟

و یک مسئله دیگه من این کد رو واسه حلقه پیغام برنامه ام می نویسم ولی اصلا" جواب نمیده :


MSG Message ;
while(GetMessage(&Message,NULL,0,0,))
{
MessageBox(NUL,"New Message","",0);
}

فرض کنید که من میخوام برنام ها به ازای هر پیغام (از فشردن کلید تا فشردن مخ یه نفر) مثلا" پیام "New Message" رو بده . ولی اصلا" این کد کار نمی کنه . برنامه ام تموم نمیشه و در حال اجرا می مونه ولی هیچ پیامی هم نمیده .
البته در مورد تابع مر بوط به پیغام های یک پنجره هیچ مسئله ای نیست و کاملا" صحیح کار میکنه .
این رو هم اگه یه نیمچه توضیح ممنون میشم . با تشکر فراوان . (خیلی خیلی زیاد )

Inprise
شنبه 19 شهریور 1384, 15:32 عصر
داریم در مورد حالات عادی حرف میزنیم نه کاربردهای خاصی مثل Injection که جزو موارد استثنائی هست که گفتم . ضمنا" سوالت مختلفت رو تو تاپیکهای مختلف با عناوین مشخص بپرس . اگر به این شکل ادامه پیدا کنه سوالات مختلف و غیر مرتبطی مطرح میشه که بعدا" نمیتونه قابل جستجو و استفاده توسط سایرین باشه .

موفق باشید

taze kar
شنبه 19 شهریور 1384, 19:35 عصر
ممنون از این که تذکر دادین .
یه سوال که مربوط به همون قضیه اول هست :
من یه تابع تعریف کردم که نه از CALLBACK برای تبدیل نوع برگشتی اون استفاده میشد و ته از LRESULT و به عنوان تابع یک پنجره که پیغام ها رو دریافت میکرد آدرسش رو فرستادم و بدون هیچ مشکلی برنامه کامپایل ,اجرا و به پیغام ها جواب داد ,بدون هیچ مشکلی . پس با این حساب چه احتیاجی به CALLBACK و ... هست ؟

واگر اشکالی نداره من سوال قبلی رو توی یک تاپیک جدید بپرسم و شما لطف کنید و مسئله رو باز کنید .
با تشکر فراوان

taze kar
شنبه 19 شهریور 1384, 19:40 عصر
البته اگر این بحث نا تراشیده یا مناسبی از نظر بار علمی نیست باید ببخشید ولی واسه من که توی این دو سه روز خیلی پر بار بوده و خیلی چیز ها یاد گرفتم . (امیدوارم با قوانین سایت مقایرتی نداشته باشه)
بسیار ممنون از راهنمایی های همه .

Inprise
شنبه 19 شهریور 1384, 23:30 عصر
اگر میخواهی بدونی Callback دقیقا" چیه : بسیاری از توابع آرگومانهائی رو به عنوان ورودی قبول میکنند فرآیندی روی بعضی از اونها انجام میشه و تغییراتی در اثر این فرایند روی بعضی دیگه انجام میشه و نهایتا یک خروجی تولید میشه . مثلا توسط یک تابع با سه ورودی ، دو ورودی اول محاسبه و نتیجه در ورودی سوم به عنوان خروجی نهائی قرار داده میشه و در صورت موفقیت آمیز بودن عملیات یک عدد صحیح از تابع بازگردانده میشه . این روند بصورت سنتی به وفور تو پیاده سازی API های ویندوز استفاده شده . گاهی لازمه برای تکمیل عملیات یک تابع بجای دریافت آرگومانهائی مثل رشته یا عدد صحیح ، یک تابع ، تابع دیگری رو به عنوان آرگومان بپذیره . مثال اول : تابع اصلی میخواد تابعی رو بگیره و اونو صدا بزنه و خروجی اش رو تو آرگومان دوم خودش قرار بده و یک صفر هم به نشان موفقیت برگردونه . مثال دوم : تابعی میخواد آرگومان اولش رو بگیره و محاسباتی روش انجام بده و اگر شرطی برقرار بود آرگومان دوم که خودش تابع دیگری است رو فراخوانی کنه و پس از اتمام ، یک صفر به نشان موفقیت برگردونه ؛ در این حالتها به تابعی که به عنوان آرگومان به تابع دیگری برای مقصود مشخصی پاس میشه Callback Function میگن ؛ یعنی تابعی که صدا زده میشه و محتویاتش اجرا میشه و سپس کنترل به برنامه اصلی برمیگرده . برای یک نمونه تابع EnumWindows رو ببین و مثالهای مربوطه رو مطالعه کن ؛

تو معرفی چنین توابعی معمولا" مغلطه متداولی اتفاق میفته ؛ عده ای خیال میکنند که تابع Callback توسط ویندوز فراخوانی میشه در حالیکه اینطور نیست . اگر تابع کال بک تو برنامهء خودت پیاده سازی شده باشه ، آدرس آفست شروعش از طریق IAT دریافت و کنترل به اون محل منتقل میشه و اگر اون تابع بالفرض یک API دیگه باشه ، چون هنگام فراخوانی برنامه ات ، تمام DLL های مورد نظر ( بصورت مجازی ) به فضای آدرسی برنامه ات منتقل شده اند ، و هر کدام آدرس ثابت و مشخصی دارند ( با استثنائاتی ) کنترل باز هم توسط برنامه ات بطور خودکار به آفست شروع API منتقل میشه . شاید چون اغلب استفاده از Callback ها توسط برنامه نویسان ویندوز به استفاده از API محدود شده ، خیلیها تصور میکنن فراخوانی Callback API توسط ویندوز انجام میشه ، در حالیکه اینطور نیست ، این فقط یکی از توابع ویندوزه که توسط برنامهء مالک ، فراخوانی میشه .

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

موفق باشی

Reza_K
یک شنبه 20 شهریور 1384, 16:35 عصر
ممنون از این که تذکر دادین .
یه سوال که مربوط به همون قضیه اول هست :
من یه تابع تعریف کردم که نه از CALLBACK برای تبدیل نوع برگشتی اون استفاده میشد و ته از LRESULT و به عنوان تابع یک پنجره که پیغام ها رو دریافت میکرد آدرسش رو فرستادم و بدون هیچ مشکلی برنامه کامپایل ,اجرا و به پیغام ها جواب داد ,بدون هیچ مشکلی . پس با این حساب چه احتیاجی به CALLBACK و ... هست ؟

واگر اشکالی نداره من سوال قبلی رو توی یک تاپیک جدید بپرسم و شما لطف کنید و مسئله رو باز کنید .
با تشکر فراوان

در مورد سوال شما: "پس با این حساب چه احتیاجی به CALLBACK و ... هست" باید بگویم یک Call back تنها مفهوم منطقی است و وجود خارجی ندارد.

در واقع Callback بمعنی تابعی است که توسط کدی غیر از کد جاری! فراخوانی می شود.

حدث میزنم، علت گمراه شدن شما وجود ماکری CALLBACK باشد. توجه داشته باشید که

1. این ماکرو به keyword ای به شکل _stdcall گسترش مییابد.

2. کامپایلر CPP به شما این امکان را میدهد که Calling Convention توابع خود را مشخص کنید(مگر اینکه تابع مورد نظر یک متد غیر استاتیک باشد که در آنصورت بصورت پیشفرض _fastcall خواهد بود).
Calling Convention مشخص کننده نحوه فرستادن پارامتر ها به آن تابع و پاکسازی stack پس از پایان کار آن تابع را مشخص میکند. مثلا _stdcall نوعی است که در آن پارامتر ها از راست به چپ در stack قرار میگیرند و در ضمن تابع فراخوانده شده مسئول پاکسازی stack میباشد. در مقابل نوع _cdecl وجود دارد که مانند _stdcall عمل میکند با این تفاوت که تابع فراخوان مسئول پاکسازی stack است.

نوع فراخوانی توابع در زبان CPP و سیستم عامل LINUX برابر _cdecl است، اما ویندوز نوع _stdcall را انتخاب کرده است. بنابر این تمامی توابع WIN32 API از نوع _stdcall بوده و درضمن انتضار دارد که اگر آدرس تابعی برای آن(ویندوز) ارسال شود، از نوع _sdtcall باشد.

در مورد اینکه چرا کد شما بدون CALLBACK و یا _stdcall کار کرده است کافیست به توضیحی که در بالا متذکر شدم دقت کنید. سناریو اینگونه است: تابع شما(بدون CALLBACK) از نوع _cdecl است و تابعی که ویندوز انتظار آدرسش را دارد از نوع _stdcall. ویندوز تابع شما با پوش کردن پارامترها در stack از راست به چپ فراخوانی میکند، تابع شما فعالیت خود را بصورت عادی انجام میدهد چون در هر دو روش _cdecl و _stdcall نحوه چیدمان پارامتر ها در stack یکسان است. اما هنگام بازگشت از تابع شما، compiler کدی برای پاکسازی stack ایجاد نکرده است و در همین حال ویندوز هم انتظار دارد که تابع شما stack را پاکسازی کند. پس تنها در صورتی که نتبع شما پارامتری نداشته باشد، وجود یا عدم وجود کلمه کلیدی _stdcall یا همان CALLBACK مشکلی ایجاد نخواهد کرد. در دیگر موارد دیر یا زود با stack corruption روبرو خواهید شد.

taze kar
یک شنبه 20 شهریور 1384, 21:01 عصر
ممنون .
پس من یک یار دیگه اطلاعات ناچیزم رو Refresh میکنم :
1 : عدم استفاده از CALLBACK و ... در منطق برنامه مشکلی بوجود می آورد ولی از آن برای هماهنگی با ویندوز و تقریبا" مدیریت حافظه استفاده میشود . به اضافه توضیحات اساتید در پست های بالا .
2 : این توابع (مثلا" همون تابع مربوط به پاسخ گویی به پیغام های یک پنجره) عملا" توسط ویندوز فراخوانی نمی شوند بلکه خود برنامه و تحت شرایط خاص .. . .. وما از CALLBACK و به عنوان سازگاری با ویندوز از آن استفاده میکنیم .


و باز یک مسئله دیگه :
من توی تابع پیغام های پنجره ام تنها تابعMesageBox رو برای پیغام های OK و CNACLE نوشتم که فقط یک بیام بده . و زمانی که برنامه رو از طریق Task Manager برسی کردم متوجه شدم که به ازای هر بار فراخوانی تابع پیغام های پنجره 2K بایت به حافظه اشغال شده برنامه اضاغه میشه . و نکته این که از CALLBACK برای تابع پنجره استفاده نکردم .

امکان دارد که دلیل این اضافه شدن حافظه ,همون کم کم پر شدن پشته باشه ؟

با تشکر فراوان .