.تعمیـــرکاران کیان ست (kiansat.kim)تابع قوانین -جمهموری-اسلامی ایران میباشد و ارسال هر گونه مطلب سیاسی،مذهبی،غیراخلاقی و خرید و فروش متعلقات ماه-واره و دیگر موارد مجرمانه ممنوع میباشد وبا کاربران خاطی به شدت برخورد میگردد انجمن فقط تعمیرات لوازم الکترونیک میباشد...













سلام مهمان گرامی؛
به کیان ست خوش آمدید برای مشاهده انجمن با امکانات کامل می بايست از طريق این لینک عضو شوید.

http://teranzit.pw/uploads/14469017281.png
پیام خصوصی به مدیریت کل سایت ........... صفحه توضیحات و شرایط گروه ویژه ........... ...........
ارتباط تلگرامی با مدیریت سایت ................. ایدی تلگرام suportripair@ .................
نمایش نتایج: از شماره 1 تا 1 , از مجموع 1

موضوع: نحوه استفاده از کدهای زبان برنامه سی c در زبان برنامه نویسی دلفی Delphi

  1. #1


    تاریخ عضویت
    Oct 2010
    نوشته ها
    198
    تشکر ها
    38
    401 سپاس از181 پست

    نحوه استفاده از کدهای زبان برنامه سی c در زبان برنامه نویسی دلفی Delphi

    انواع فراخواني توابع
    توابع در يک زبان برنامه نويسي بسته به روش فرستادن آرگومانها به تابع، جهت قرار گرفتن آرگومانها در پشته و يا رجيسترها و نوع پاکسازي پشته بعد از پايان تابع، به چند دسته تقسيم ميشوند.:
    1. register
    در اين نوع براي فرستادن آرگومانها به تابع از ثباتهاي حافظه (رجيسترها) استفاده ميشود. در اين حالت آرگومانها از چپ به راست در رجيسترها قرار گرفته و به تابع پاس داده ميشوند. اين نوع توابع خودشان بعد از پايان کار فضا و پشته را خالي ميکنند. نوع فراخواني پيشفرض براي دلفي حالت register است.
    2. pascal (__pascal در C)
    در اين نوع، آرگومانها از طريق پشته (Stack ) به تابع فرستاده ميشوند، آرگومانها از چپ به راست در پشته قرار ميگيرند و تابع بعد از پايان کار و پيش از بازگشت پشته را خالي ميکند. اين حالت صرفا براي پشتيباني از کدهاي قديمي هنوز پشتيباني ميشود.
    3. cdecl ( __cdecl در C )
    آرگومانهاي اين نوع، از طريق پشته به تابع فرستاده ميشوند و از راست به چپ در پشته قرار ميگيرند. تابع بعد از پايان کار پشته را خالي نميکند و صدازننده تابع بايست اين کار را انجام دهد. حالت پيشفرض در C و براي توابع سيستمي براي سيستم عامل هاي غير ويندوز همين نوع است.
    4. stdcall (__stdcall در C )
    آرگومانها از طريق پشته و از راست به چپ به تابع فرستاده ميشوند. تابع بعد از پايان کار پشته را خالي ميکند. کليه API هاي سيستم عامل ويندوز از اين نوع هستند.
    5. safecall (__safecall در C )
    اين نوع فراخواني دقيقا شبيه حالت stdcall است با اين تفاوت که در برابر خطاهاي اتفاق افتاده در تابع مثل يک ديوار عمل ميکند و خطا را (در صورتي که در تابع تله گذاري نشده باشد ) به صدا زننده تابع برنميگرداند و معمولا براي پياده سازي تکنولژي COM از آن استفاده ميشود. در این نوع تابع، بازگشتی به صورت آرگومان آخر فرستاده میشود (به عبارتی یک آرگومان به تابع اضافه میشود ) و بازگشتی اصلی به صورت HRESULT میشود که در صورت موفقیت کد S_OK و در غیر اینصورت خطای اتفاق افتاده را باز میگرداند.
    فراخواني تابعي از يک نوع به نوع ديگر باعث خطاهايي خواهد شد که تشخيص آن هنگام برنامه نويسي نسبتا مشکل است.
    البته منظور از طريقه پاکسازي پشته يا طريقه فرستادن آرگومانها اين نيست که برنامه نويس بايستي خودش اين کار را انجام دهد، کامپايلر هنگام کامپايل عمليات لازم مربوط به اين مراحل را به کد اضافه ميکند.
    حالتهاي توصيه شده براي توابع در ويندوز stdcall و safecall هستند. براي مشخص کردن نوع تابع در دلفي کافي است يک از کليدواژه هاي معرفي شده را در پايان معرفي تابع قرار دهيم :
    function MyFunc(Arg1 : Integer ; Arg2 : Integer):Integer;stdcall;
    در C بايستي نوع تابع را قبل از نام تابع و بعد از نوع بازگشتي مشخص کنيم :
    int __stdcall myfunc (int arg1, int arg2 );
    همانطور که گفته شد دلفي توابع بدون مشخصه را register و C آنها را cdecl در نظر ميگيرد.
    کامپايلر هاي C معمولا هنگام کامپايل يک علامت زيرخط (_) به آغاز نام توابع cdecl اضافه ميکنند و نام توابع نوع pascal تماما به حروف بزرگ تبديل ميشود.
    کامپايل فايلهاي C توسط Borland C++ Builder به فايلهاي Obj
    طريقه کامپايل فايل هاي c و تبديل آنها به فايلهاي obj بدون ايجاد فايل نهايي بسيار ساده است. دستوري شبيه زير را از طريق خط فرمان يا يک Batch فايل اجرا کنيد
    BCC32.EXE [options] file1.c file2.c …
    به جاي BCC32.EXE آدرس کامل اين فايل (که در پوشه bin در مکان نصب C++ Builder قرار دارد) را بنويسيد و به جاي options انتخابهايي را که چندتايي از آنها در ادامه معرفي ميشوند و بالاخره در انتها ليست فايلهايي که ميخواهيد کامپايل کنيد را بنويسيد. مثلا :
    C:BorlandBCC55BinBCC32.EXE -c -X -v -u- test1.c test2.c
    حروف کوچک و بزرگ در مورد انتخابها (options ) مهم هستند اما در مورد نام فايلها نه. هر انتخاب با يک علامت منفي (-) در سمت چپ مشخص ميشود و گذاشتن يک منفي در سمت راست به معني حذف اين انتخاب از ليست انتخابهاست.بعضي option ها که مورد نياز هستند را در اينجا توضيخ ميدهيم. باقي اين موارد را ميتوانيد در راهنمايC++ Builder ببينيد.
    -c : اين انتخاب به کامپايلر اعلام ميکند که بعد از پايان کامپايل Linker را فراخواني نکند و به جاي ساختن فايل نهايي (فايل exe يا dll و يا... ) فقط فايلهاي Obj را بسازد.
    -X : اين انتخاب باعث ميشود که کامپايلر طلاعات مربوط به فايلهاي سرآمد (Header فايلهاي C ) را به فايل Obj اضافه نکند. در حالت عادي کامپايلر اين کار را ميکند. دلفي نيازي به اين اطلاعات ندارد و ان انتخاب حجم فايلهاي Obj را کم ميکند.
    -v :اين انتخاب اطلاعات مربوط به Debug را نيز به Obj فايل اضافه ميکند. اين به شما اجازه ميدهد هنگام تست برنامه در دلفي و Trace آن از طريق کليد F7 کد C را هم در محيط دلفي دنبال کنيد. (البته در صورتي که اصل فايلها به زبان C موجود باشد و شما تنها Obj فايلها را نداشته باشيد.) اين انتخاب اندازه فايلهاي Obj را تا خد زيادي افزايش ميدهد و تنها براي زماني مناسب است که برنامه در مرحله تست و خطايابي است. در هنگام انتشار بهتر است اين انتخاب هنگام کامپايل برداشته شود.
    -u- : هنگام کامپايل، کامپايلر C++ Builder يک علامت زيرخط (_) به توابع با نوع فراخواني cdecl اضافه ميکند (حالت پيشفرض -u است) شما با گذاشتن يک منفي در سمت راست ميتوانيد اين گزينه را غير فعال کنيد. در اين صورت کليه توابع cdecl با نام خودشان در فايل Obj قرار ميگيرند.
    -pr : نوع فراخواني پيشفرض توابع را از cdecl به register تبديل ميکند. در اين حالت تمام توابعي که نوع فراخواني آنها مشخص نيست به نوع register تبديل ميشوند.
    افرودن فايلهاي Obj به کد دلفي
    به دليل شباهت لينکرهاي C++ Builder و Delphi براي افزودن يک فايل Obj کامپايل شده توسط C++ Builder - و البته خود دلفي - به دلفي ميتوانيد از دستور پيش پردازنده $L استفاده کنيد. مثلا {$L fileName.obj} و سپس کافي است کليه توابعي که در فايل Obj هستند و نيازمند استفاده از آنها در C هستيد را با يک اعلان پيشرو و به صورت external تعريف کنيد. در اين حالت توابع مورد استفاده که با کامپايلر C++ Builder کامپايل شده اند با لينکر دلفي به برنامه لينک ميشوند.نمونه اين کار ببينيد:

    کد:
    کد سي : 1. /* 2. Link C File in delphi 3. Author : F0ruD 4. */ 5. char* __cdecl strncpy(char* dest,char* source,int count); 6. 7. void __stdcall FillBuf ( char *buf , int len) 8. { 9. const char msg[]="this is a message from c code"; 10. int i; 11. i=(strlen(msg) > len?len:strlen(msg)); 12. strncpy(buf,msg,i); 13. } کد دلفي : 1. unit uLink; 2. 3. interface 4. uses SysUtils, Dialogs; 5. 6. procedure TestLink; 7. implementation 8. //Link obj file to program 9. {$L test.obj} 10. 11. procedure FillBuf(Buf: PChar; Len: Integer); stdcall; external; 12. 13. //This function called in C program. But there is no 14. //definition of this functionin C file. 15. //So linker search Delphi code for this 16. //function. It meens we need Define this function. 17. 18. function _strncpy(Dest: PChar; Source: PChar; Count: Integer): PChar; cdecl; 19. begin 20. Result := StrLCopy(Dest, Source, Count); 21. end; 22. 23. function _strlen(Str: PChar): Integer; cdecl; 24. begin 25. Result := StrLen(Str); 26. end; 27. 28. procedure TestLink; 29. var 30. Buf : array[0..124] of Char; 31. begin 32. FillChar(Buf, SizeOf(Buf), 0); 33. FillBuf(Buf, 124); 34. ShowMessage(Buf); 35. end; 36. 37. 38. end. 39. 40.
    کليه دستورات کليدي C از قبيل for يا while ... بدون هيچ محدوديتي مجاز هستند. تمام قوانين مربوط به آرايه ها، اشاره گرها و... نيز بايستي بدرستي رعايت شوند. اما کامپايلر هنگام کامپايل نيازي به اعلان پيشروي توابع ندارد. در صورتي که در زبان C از هر تابعي که استفاده ميشود يا بايد در يک فايل سرآمد در برنامه include شده باشد يا اين که در همان برنامه تعريف شده باشد. اگر بعد از جايي که از آن تابع استفاده ميشود تعريف شده باشد يک اعلان پيشرو قبل از استفاده از تابع لازم است.
    اما هنگام کامپايل وقتي کامپايلر به فراخواني يک تابع برسد کليه هدرفايلها و قسمت بالايي جايي را که به تابع رسيده دنبال خود تابع يا اعلان پيشرو آن ميگردد. در صورتي که اعلان پيشرو يا خود تابع را پيدا کند نوع فراخواني آن را در نظر گرفته و تابع را با نوع فراخواني در آن نقطه صدا ميزند. اما در صورتي که به هيچکدام از اين دو (اعلان پيشرو يا خود تابع) برخورد نکند تابع را با نوع پيشفرض (در حالت عادي cdecl مگر اينکه با انتخابي شبيه -pr حالت پيشفرض عوض شده باشد) صدا ميزند ولي خطايي مبني بر پيدا نکردن تابع اعلام نميکند.در اصل کامپايلر فرض ميکند که تابع هنگام لينک پيدا ميشود و در هنگام لينک، لينکر اين مساله را بررسي خواهد کرد.
    در مثال بالا توابع strlen و strncpy در برنامه C صدا زده شده اند. هيچ هدر فايلي در برنامه اضافه نشده (اين باعث ميشود که برنامه در C قابل اجرا نباشد و اين به عمد صورت گرفته است. در صورتي که معمولا برنامه ها طوري نوشته ميشوند که در C قابل اجرا باشند.) وتنها تابع strncpy با اعلان پيشرو در برنامه اعلان شده است. در اين مثال کامپايلر هنگام رسيدن به تابع strlen چون آن را در بالاتر يا در هيچ هدر فايلي پيدا نميکند به صورت cdecl در نظر ميگيرد. تابع strncpy هم با اعلان cdecl به صورت پيشرو تعريف شده است بنابراين کامپايلر آن را هم از اين نوع در نظر ميگيرد.
    در صورتي که برنامه سي را با انتخاب -pr کامپايل کنيم تابع strlen به صورت register تعريف ميشود اما تابع strncpy به علت وجود اعلان پيشرو همچنان به صورت cdecl تعريف ميشود. دقت کنيد در صورتي که از هدرهاي استاندارد سي استفاده ميکنيد نوع فراخواني توابع را در نظر داشته باشيد.(معمولا cdecl )
    هنگامي که اين کد را با فايل دلفي لينک ميکنيم لينکر دلفي بدنبال توابع _strncpy و _strlen ميگردد. و ما بايستي آنها را در کد دلفي و بعد از جايي که کد به برنامه لينک شده تعريف کنيم. (به تعريف اين دو تابع در کد دلفي توجه کنيد) اين زيرخط تضمين ميکند که توابع همنام در دلفي و سي (مثل strlen و توابع مشابه ديگر ) با هم اشتباه گرفته نميشود. تعريف اين توابع مشابه در محيط سي به فرمي غير از cdecl ميتواند باعث خطاهاي ناخواسته و ناخوشايندي شود. مثلا با تعريف اين تابع به صورت پيشرو و از نوع stdcall باعث ميشود که لينکر دلفي به دنبال تابع strlen بگردد و اين تابع را در کتابخانه هاي use شده در محيط دلفي ميابد. در صورتي که اين توابع کتابخانه اي از نوع register هستند که اين باعث خطاي زمان اجرا (و نه خطاي زمان کامپايل ) ميشود. تنها راه مناسب اين است که برنامه c را با گزينه -pr کامپايل کنيم تا توابع همنام در دلفي و سي به جاي هم استفاده شوند يعني با کامپايل کد سي در مثال شما نيازمند دوباره نويسي تابع strlen نخواهيد بود اما تابع strncpy چون به صورت پيشرو تعريف شده و هم اينکه در کتابخانه دلفي با تابع مشابه خود همنام نيست بايستي دوباره در دلفي نوشته شود مگر اينکه در کد سي از تابع strlcopy استفاده شود که گر چه در کتابخانه سي نيست اما هنگام الحاق به دلفي مشکلي پيش نمي آيد. از گزينه -pr بهتر است در حالت عادي استفاده نشود چون ميتواند مشکلاتي را در مورد توابع همنام يا آرگومانها و يا ترتيب آرگومان غير مشابه بوجود بياورد.
    افزودن چند فايل Obj به برنامه
    کد:
    نمونه زير راببينيد : فايل test1.c 1. /* 2. Link C File in delphi 3. Author : F0ruD 4. */ 5. void __stdcall FillBuf(char *buf,char ch,int len) 6. { 7. int i; 8. for (i=0;i<len;i++) 9. *(buf+i)=ch; 10. *(buf+len)=0; 11. } فايل test1.h 1. #ifndef _TEST1_H_ 2. # define _TEST1_H_ 3. 4. void __stdcall FillBuf(char *,char,int); 5. 6. #endif 7. فايل test2.c 1. #include "test1.h" 2. 3. void __stdcall ZeroBuf(char *buf,int len) 4. { 5. FillBuf(buf,0,len); 6. } کد دلفي : 1. unit uLink; 2. 3. interface 4. uses SysUtils, Dialogs; 5. 6. procedure TestLink; 7. implementation 8. 9. procedure ZeroBuf(Buf: PChar; Len: Integer); stdcall; external; 10. //Link obj files to program 11. {$L test2.obj} 12. {$L test1.obj} 13. 14. 15. 16. procedure TestLink; 17. var 18. Buf : array[0..124] of Char; 19. begin 20. Buf := 'This message must fill with 0'; 21. ZeroBuf(Buf, 124); 22. ShowMessage(Buf); 23. end; 24. 25. 26. end. 27. 28.
    اين مثال نشان ميدهد که چگونه ميتوان از توابع نوشته شده در يک فايل ديگر c در يک فايل ديگر استفاده کرد. وجود فايل هدر test1.h صرفا براي اعلان پيشروي تابع استفاده شده و به اين صورت کامپايلر هنگام کامپايل نوع تابع FillBuf را به صورت cdecl در نظر گرفته است. البته تابع FillBuf نيز در برنامه دلفي قابل استفاده است.
    در صورتي که ترتيب لينک شدن اين دو فايل را عوض کنيم با خطا روبرو خواهيم شد چرا که لينکر دلفي بعد از لينک در قسمت پاييني کد دنبال تابع FillBuf ميگردد.
    [CENTER]:1205219183:
    [B][FONT=Tahoma][SIZE=3][COLOR=#0000ff][URL="http://kiansat3.ir/showthread.php?t=47100"]فروش جدیدترین و کاملترین پکیج نرم افزاری و بازی و آموزشی و تعمیراتی انواع موبایل ها بصورت کاملا فارسی به همراه چندین اشانتیون[/URL][/COLOR][/SIZE][/FONT][/B]
    [B]:1205219183::فقط خودت باش نه کسی دیگر!
    :lay:
    [/B][/CENTER]

  2. 4کاربر از Borna66 بخاطر ارسال این پست مفید سپاسگزاری کرده اند:

    ARIYA (5th May 2012),KIAN FAR (4th May 2012),masoud-sat (4th May 2012)

اطلاعات موضوع

کاربرانی که در حال مشاهده این موضوع هستند

در حال حاضر 1 کاربر در حال مشاهده این موضوع است. (0 کاربران و 1 مهمان ها)

کلمات کلیدی این موضوع

مجوز های ارسال و ویرایش

  • شما نمیتوانید موضوع جدیدی ارسال کنید
  • شما امکان ارسال پاسخ را ندارید
  • شما نمیتوانید فایل پیوست کنید.
  • شما نمیتوانید پست های خود را ویرایش کنید
  •  


Copyright ©2000 - 2013, Jelsoft Enterprises Ltd کیــــــــــان ستـــــــــــ ...® اولین و بزرگترین سایت فوق تخصصی الکترونیک در ایران



Cultural Forum | Study at Malaysian University