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

شروع موضوع توسط SajjadKhati ‏30 آوریل 2016 در انجمن منطق و الگوریتم برنامه‌نویسی

  1. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    سلام
    یکی از دوستام گفت توی #C یه dll نوشته و اونو برده داخل CLI ++C (سی پلاس پلاس سی ال آی) و توی این زبان عملیاتی روش انجام داده از اونجا دوباره خروجی گرفته بصورت dll و توی لوا تونسته اجرا کنه
    میگفت چون خیلی مدت پیش این کار رو کرده و نمونه پروژه شو از دست داده ، یادش نیست
    منم CLI ++C بلد نیستم
    نمیدونین چی کار کرده؟ و یا لینک آموزشی ، چیزی بهم در این باره میدین که باید بعد از انجام و ایجاد کلاس و ساخت dll در سی شارپ ، توی CLI ++C باید چه کارهایی کرد و چجوری خروجی گرفت که در زبان های غیر مجازی ، اجرا شه؟
     
    نوشته شده توسط SajjadKhati در ‏30 آوریل 2016
  2. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    اگه من راهی برای این ارتباط سراغ داشتم که نیازی به پاسکاری بین دو زبان NET. ای نبود. کامپایلر C++ CLI با #C و Visual Basic .NET فرقی نداره.
    همانطور که قبلا اشاره کرده بودم برای ++C در ویژوال استدیو دو نوع کامپایلر داره، البته کد های زبان شان عینا یکی نیست. میشه بین گزینه Native که برای ماشین واقعی کامپایل میشه و CLI/CLR که برای ماشین مجازی کامپایل میشه
    و مشابه #C از امکانات NET. استفاده می کنه انتخاب کرد. اینکه یک زبان NET. از dll یک زبان دیگه NET. استفاده کنه کاملا مرسوم ئه، شما می توانید خروجی هر کدوم از Visual Basic .Net و #C و C++ CLI رو در دیگری بکار ببرید
    و حتی یک Solution با ترکیب چندین پروژه از زبان های مختلف NET. بسازید. اما تا آنجایی که اطلاع دارم باز نهایتا در C++ CLI یک پروژه NET. ای می سازید که کلاس هایی رو برای سایر زبان های NET. ارائه می کنه،
    DLL استاندارد ویندوز با توابع stdcall و fastcall نمی سازه. در DLL استاندارد توابع بدون کلاس Export می شوند. در زبان های NET. همه توابع داخل یک ساختار یا کلاس قرار گرفته.
    شما هر نوع پروژه ای که در C++ CLI برای ساختن DLL انتخاب کنید نهایتا حداقل یک کلاس خواهد داشت، شما که به کلاس های NET. در لوا دسترسی نخواهید داشت.
     
    نوشته شده توسط the_king در ‏30 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  3. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    ممنون آقا علی
    نمیدونم والا
    این دوستم هم پروژه رو ساخت
    پس چی کار کرد؟
    اتوپلی میتونه توابع STDcall و CDECLcall رو فراخونی کنه
    البته لوا هم کلاس و شی گرایی رو ساپورت میکنه ولی ساختارش کاملا متفاوت با شی گرایی در #C هه . ساختار شی گرایی در لوا بوسیله ی آرایه هست
    یه ماژول NLua هم هست برای لوا که انگار باعث ارتباط بین لوا و زبان های دات نت میشه ولی نمیدونم چجوری کار میکنه :

    http://nlua.org/
     
    نوشته شده توسط SajjadKhati در ‏30 آوریل 2016
  4. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    یک مفسر لوا برای #c ئه، در برنامه #c تان می توانید رشته هایی از کد به زبان لوا بسازید و اجرا کنید.
     
    نوشته شده توسط the_king در ‏30 آوریل 2016
    SajjadKhati از این پست تشکر کرده است.
  5. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    ممنون
    آخه برای نوشتن لوا توی سی شارپ ، ماژول های دیگه انگار هست مثل LuaInterface و LuaNet . این قدر اسماشون شبیه هم هست که آدم نمیدونه کدوم چی کار میکنه !
    الان پس این دوستم چجوری کد نوشت با CLI ؟!!
    این مشکل حل شه ، یه پل بزرگی میشه که خیلی ها راحت میشن
     
    نوشته شده توسط SajjadKhati در ‏30 آوریل 2016
  6. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    خیلی از پروژه ها کاربرد های مشابه دارند، مثلا برای تبدیل فرمت تصویری یا خروجی pdf گرفتن انواع کتابخانه ها و کمپوننت ها هست، طبیعتا هر کدوم مزایا و معایبی دارند، تا امتحان شون نکنید مشخص نمیشه که
    کدوم مورد با کاربرد و سلایق شما منطبق تره.

    امتحان کردم، C++ CLI دقیقا به همون شیوه ای که در ++C های Native فایل DLL می ساختید تابع Export می کنه، اما تبدیل نوع داده رو باید انجام بدهید و اگر انواع داده پیچیده تر رو بکار ببرید یکسری موارد مربوط به توابع Marshal رو باید یاد بگیرید.
    یک پروژه #C طراحی کردم که یک کلاس با دو متد داره، یک پروژه C++ CLR که دو تا متد با همون مشخصات رو با stdcall به بیرون Export می کنه و متد های همون پروژه #C رو فراخوانی می کنه،
    به اصلاح این پروژه دوم یک Wrapper ئه. یک پروژه مثال Visual Basic 6 هم نوشتم که از اون فایل dll استفاده کنه. برای انواع داده ای ساده ای مثل int مستقیم جواب میده و برای انواع داده ای پیچیده تری مثل string
    احتیاج به تبدیل مقدار هست. در مثال همچین موردی رو ننوشتم اما کلا C++ CLR مثل سایر زبان های NET. حافظه اش توسط خود زبان خودکار مدیریت میشه و garbage collector داره و اگر بخواهید یک حافظه مستقل ای مثل آرایه
    رو به بیرون از محیط بفرستید و return کنید باید خودتون حافظه اش رو مدیریت کنید، چون دیگه ++C و #C مسئول آزاد کردن حافظه ای نیستند که به بیرون از محیط NET. می فرستید. اگر مدیریت درست انجام نشه و به موقع در بیرون
    حافظه رو آزاد نکنید به اصلاح Memory Leak پیش میاد و حافظه همونطور اشغال میمونه و آزاد نمیشه و به تدریج که برنامه در حال اجرا است حافظه آزاد سیستم رو کم می کنه.

    به مثال پیوستی مراجعه کنید،
    مشاهده پیوست Sample.zip
     
    نوشته شده توسط the_king در ‏1 می 2016
    SajjadKhati از این پست تشکر کرده است.
  7. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63

    ممنون آقا علی
    آره این دوستمم میگفت همین مشکل آزادسازی رم رو ولی حالا ارتباط رو برقرار بشه . رم فقط به اندازه ی متغییر ها و آرایه ها و ... ای که اشغال کرده میخواد اشغال کنه بعد دیگه تا ریستارت کردن سیستم ، پاک نشه دیگه؟
    واسه من کلاس های نوشته شده در پوشه ی Sample_Output برای SampleCS.dll و SampleCLR.dll رو نشون نمیده در object viewer .
    من ++c بلد نیستم و نمیدونم چجوری باید فایل هاشو باز کنم و کلاس ها و متدهاشو ببینم که ورودی و خروجی اش چی ان . الان فایلی که من توی اتوپلی باید فراخونی کنم ، SampleCLR.dll در پوشه ی Sample_Output هست؟ اگه آره ، متدها و ورودی و خروجی اش چی هستن و چی کار میکنن؟ بصورت stdcall هستن؟
    بعد اینکه یه لینکی چیزی میدین که آموزش خروجی گرفتن توی CLI ++C رو آموزش بده؟ یعنی چجوری پروژه ای که توی سی شارپ نوشته شد را داخل CLI ++C وارد و چجوری خخروجی بگیریم که بصورت stdcall باشه و توی لوا قابل فراخونی باشه؟

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

    بعد میشه غیر از ساخت dll ، پروژه ای رو بصورت کنسولی نوشت و فایل exe ی کنسولی رو در نرم افزارهای دیگه (مثلا اتوپلی) فراخونی کرد؟ ابزار nircmd که محیط cmd داره رو میشه با اتوپلی همزمان با اینکه فایل رو اجرا میکنیم ، رشته ی مورد نظر رو برای ورودی هایی که nircmd داره ، بدیم و کار میکنه اما توی سی شارپ که یه برنامه ی کنسولی نوشتم ، این جوری از طریق اتوپلی اجرا میکنم ، با اونکه آرگومان هاش رو میدم ولی چیزی توش (توی محیط cmd اش) نمینویسه و بنابراین ورودی دریافت نمیکنه و ادامه ی برنامه اجرا نمیشه (فقط فایل اجرایی اش ، اجرا میشه)
     
    نوشته شده توسط SajjadKhati در ‏1 می 2016
  8. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    منظورتون Object Browser ئه؟ اگه بهشون Reference بدهید هر دو رو نشون میده، اما صرفا SampleCS.dll کلاس و فرم هایی برای نشون داده داره، تو SampleCLR.dll چیزی نیست که بخواد نشون بده، خالی ئه. اون دو تا تابع export شده
    Type Library نداره که نشون شون بده، اما ابزار هایی مثل Dependency Walker می تونه اسم توابع داخل dll رو نشون بده.

    توی پوشه Sample_Output و Sample_VB6.exe نمونه فایل اجرایی هست. توابع stdcall اند، اگه پروژه #C رو باز کنید مشخص میشه که چیکار می کنند.
    کد (Text):

    void __stdcall ShowMessage(const wchar_t* title, const wchar_t* message)
    int __stdcall MultiplyRange(int value1, int value2)
     
    شیوه export گرفتن از توابع ++C مشخص ئه. رجوع شود به طریقه ساخت dll در C++

    برای بکار بردن یک پروژه NET. در یک پروژه دیگه NET. هم روال مشخصه. پروژه ++C تون رو باز می کنید، اگه قصد تغییر مکرر کد رو ندارید موقع Add Reference کردن تو زبانه Browse به فایل کامپایل شده (مثلا DLL) اون پروژه #C یا VB.NET یا
    هر پروژه NET. دیگری Reference می دهید، یا اگر کد DLL تون در حال تکمیل ئه تو منوی File با گزینه Add > Existing Project مستقیما پروژه اش را به Solution اضافه می کنید و بعد موقع بکار بردن Add Reference تو زبانه Projects میاد.
    اما اینکه یه کد #C که معلوم نیست چیه رو چطور تو یک پروژه C++ CLI دیگه Wrapper کنیم که تو لوا درست فراخوانی بشه سوالی نیست که بتونم جواب بدم.

    برنامه کنسولی یک حالت داره، اجرا میشه. آرگومان های چی رو میدید؟ وقتی کد پروژه کنسولی رو خودتون می نویسید خودتون هم مشخص می کنید که آرگومان ها چی هستند و چه کاری انجام می دهند.
    اگر جایی از کد چیزی از CommandLine نخوانید از بیرون هیچ برنامه دیگری همچین قابلیتی به فایل شما اضافه نمی کنه.
    با Environment.GetCommandLineArgs مواردی که به فایل اجرایی ارسال شده بصورت آرایه دریافت می کنید. اولین عضو همیشه اسم فایل اجرایی است، مثلا اگر test.exe sample "My Documents" 123 اجرا بشه آرایه چهار عضوی دریافت می کنید. به ترتیب رشته های test.exe و sample و My Documents و 123
    کد (Text):

                string[] args = Environment.GetCommandLineArgs();
     
     
    نوشته شده توسط the_king در ‏2 می 2016
    SajjadKhati از این پست تشکر کرده است.
  9. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    ممنون آقا علی
    ببخشید این فایل dll ای که اسمش SampleCLR.dll هست ، داخل پروژه ی #C فراخونی و استفاده نمیشه دیگه؟ اگه آره ، چجوری میشه؟ من dll شو add reference کردم ولی نه نام فضای نام اش که SampleCS بود رو میشناسه (بعد از using کردن) و نه نام کلاس و متدهاشو
    توی اتوپلی هم با اونکه stdcall هست و نرم افزار dllexp توابع شو میشناسه ، ولی توی اتوپلی انگار مقداری رو برنیگردونه که در حال پیگیریش هستم
    بازم ممنون
    :rose:
     
    نوشته شده توسط SajjadKhati در ‏2 می 2016
  10. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    ممنون آقا علی
    آقا علی من هر کار میکنم این تابع برام عمل نمیکنه
    دوستم میگه به نظرش موقع خروجی گرفتن باید یه گزینه ای بنام publish زده بشه تا هر فایل و چیز وابسته ای که نیاز داره رو خروجی بگیره همراش وگرنه توی سیستم بعضی ها فراخونی نمیشه
    با اون حال ، بازم نمیدونم مشکل از کجاست
     
    نوشته شده توسط SajjadKhati در ‏2 می 2016
  11. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    نه، اون SampleCLR.dll از dll پروژه #C استفاده می کنه، ارتباط یک طرفه است، خودش هیچ کاربردی در پروژه #C نخواهد داشت. باز هم تکرار می کنم، تو SampleCLR.dll چیزی نیست که Object Browser بخواد نشون بده، خالی ئه. اون دو تا تابع export شده Type Library نداره که نشون شون بده
    کلاسی در پروژه C++ CLR ننوشته ام که بخواهد نشان بدهد.

    چیزی همراهش نیست، کلا دو تا فایل dll اند که هر دو هم از Microsoft .NET Framework استاندارد استفاده می کنند. نه از MFC استفاده می کنه و نه ATL
    اگه فایل Sample_VB6.exe درست کار می کنه پس DLL ها هم مشکلی ندارند.
     
    نوشته شده توسط the_king در ‏2 می 2016
    SajjadKhati از این پست تشکر کرده است.
  12. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63

    ممنون
    نه
    فایل Sample_VB6.exe هم برام کار نمیکنه . یعنی وقتی دکمه رو میزنم ارور میده میگه فایل SampleCLR.dll وجود نداره در حالی که این فایل dll به همراه اون یکی فایل dll ، در کنار این فایل exe هستن
     
    نوشته شده توسط SajjadKhati در ‏2 می 2016
  13. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    عجب، محتویات پوشه رو در یک درایوی بجز :c از حالت فشرده خارج کنید و قرار بدهید.
     
    نوشته شده توسط the_king در ‏2 می 2016
    SajjadKhati از این پست تشکر کرده است.
  14. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    روی درایو h هست
    از ارورش عکس بگیرم و بزارم؟
    الان دوستم میگفت گزینه ای شبیه به publish باید بزنیم تا همه ی فایل های مورد نیاز رو خروجی و یکجا جمع کنه ، چیه؟
     
    نوشته شده توسط SajjadKhati در ‏2 می 2016
  15. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    بعضی از انواع پروژه های اجرایی که باید تحت وب اجرا بشوند و یا نصب آنلاین / آفلاین و آپدیت دارند گزینه و تنظیمات Publish دارند.
    یک بخش اجرایی دارند با یکسری فایل های Runtime که برای اجرای اون باید نصب باشه که کنارش قرار می دهند که اجراش قطعی باشه.
    مربوط پروژه های غیر اجرایی مثل این پروژه Class Library نیست که فقط یک dll دارند.

    این رو دانلود کنید و روی سیستم نصب کنید :
    Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)
    Microsoft Visual C++ 2008 SP1 Redistributable Package (x64)
    و این نسخه Release رو جایگزین اون نسخه Debug کنید که احتیاج به نصب شدن ویژوال استدیو نداشته باشه :
    مشاهده پیوست SampleCLR.zip
    نسخه Release برای انتقال نهایی روی سیستم کاربر ئه، برای اشکال گیری از کد مناسب نیست.
    نمی دونم نسخه ویژوال استدیو تون چیه، ولی اگه ویژوال ++C رو نصب نکنید و پروژه ++C رو توش باز نکنید و Build نکنید نمی توانید نسخه Debug بسازید که برای اشکال گیری از کد لازمه.
     
    نوشته شده توسط the_king در ‏3 می 2016
    SajjadKhati از این پست تشکر کرده است.
  16. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63

    ممنون آقا علی
    الان اون ویژال بیسیک هه درست شد (نمیدونم بخاطر نصب Microsoft Visual C++ Redist... بود یا وقتی ویژال استودیو رو نصب داریم ، نیاز به نصب اون نیست)
    ولی توی اتوپلی فراخونی نمیشه باز . فکر کنم بخاطر اینه که یه dll ، از یه dll دیگه استفاده میکنه. نمیشه کلا یک dll واحد بشن؟
    نسخه ی ویژال استودیو ام 2015 هست
     
    نوشته شده توسط SajjadKhati در ‏3 می 2016
  17. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    چرا نشه، با #c کد ننویسید و کل کد تون رو در c++ clr بنویسید، کم کم حکایت شیر بی یال و دم میشه.
     
    نوشته شده توسط the_king در ‏3 می 2016
    SajjadKhati از این پست تشکر کرده است.
  18. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63
    ممنون
    منظورم اینه که توی #C بنویسیم و توی ++C خروجی بگیریم وگرنه کار کردن با ++C سخت هه
    فرق clr و cli چیه؟
    آخه دوستم میگفت توی cli نوشت
    فرقی با هم ندارن؟
    ----------------
    من الان یه تابع در کلاس CLR ++C نوشتم و بعد از منوی build گزینه ی
    build solution رو زدم ولی dll من بصورت stdcall نشد (بعد اینکه باید کل کلاس شو و خود متد و اعضای متد ام رو static تعریف کنم؟)
    کد من اینه :


    کد (Text):

    // MyTestCPPCLR.h


    #pragma once


    using namespace System;


    namespace MyTestCPPCLR {


        public ref class Class1
        {
            // TODO: Add your methods for this class here.
            int MyMethod(int a, int b) {
                int c = a + b;
                return c;
            }
        };
    }
     
     
    آخرین ویرایش: ‏3 می 2016
    نوشته شده توسط SajjadKhati در ‏3 می 2016
  19. the_king

    the_king مدیرکل انجمن

    ارسال‌ها:
    10,340
    تشکر شده:
    10,283
    امتیاز دستاورد:
    113
    هر دو شون یک زبان اند، اما گستردگی مفهوم C++ CLI بیشتر از C++ CLR ئه، چون C++ CLR پیاده سازی مختص مایکروسافت ئه، ولی C++ CLI یک استاندارد ئه که الزاما فقط خاص محصول مایکروسافت نیست.
    CLI اسم زیر-ساخت ای است که NET Framework. و Mono و هر پیاده سازی سازگار با اونها بکار می برند.
    CLR اسم ماشین مجازی ای است که NET Framework. و زبان های تحت اون بکار می برند و مختص مایکروسافت ئه.
    از اونجایی که ++C پیاده سازی مختلف و ناسازگاری داره CLI یا CLR رو بهش اضافه می کنند تا مشخص کنند منظور این نوع پیاده سازی خاص ئه که از CLI یا CLR استفاده می کنه.
    اگه بگید با C++ CLR برنامه نویسی می کنید متوجه می شوند که با Microsoft .NET Framework و Visual Studio کار می کنید، ولی C++ CLI در Mono و Portable.NET و ... هم پیاده سازی شده.

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

    کلاس رو پاک کنید. شما برای توابعی که export می کنید کلاس نمی خواهید.
    هم باید فایل def بسازید و هم extern "C" __stdcall رو اضافه کنید.
    کد (Text):

        [B][COLOR="#0000FF"]extern "C"[/COLOR][/B] int [B][COLOR="#0000FF"]__stdcall[/COLOR][/B] MultiplyRange(int value1, int value2)
        {          

        }
     
     
    نوشته شده توسط the_king در ‏3 می 2016
    SajjadKhati از این پست تشکر کرده است.
  20. SajjadKhati

    SajjadKhati کاربر فعال <A href="http://forum.majidonline.com/f

    ارسال‌ها:
    756
    تشکر شده:
    266
    امتیاز دستاورد:
    63

    ممنون
    فایل def چیه؟
    الان وقتی بدنه ی این تابع رو طبق دستوری که دادید ، نوشتم ، بعدش از منوی build گزینه ی build solution رو بزنم مگه کافی نیست؟ و بعدش هم از فایل dll ای که ساخته شد استفاده کنم؟!
     
    نوشته شده توسط SajjadKhati در ‏3 می 2016

به اشتراک بگذارید