یوهو پیدا کردم بعد از یه قرن
خدایا شکرت
الان در پوست خودم گنجایش ندارم برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
باز هم معنای إِن تَنصُرُوا اللَّهَ يَنصُركُم که امام خامنه ای گفت برام مجسم شد
استاد علی خیلی از راهنمایی تون ممنونم . واقعا لطف بزرگی کردین . دیگه هم لازم نیست وقتم رو روی زبان های دیگه برای ساخت dll برای زبان لوا صرف کنم
تجربه ی خودمو بگم تا فراموش نکردم
آموزش ساخت dll در #C برای زبان های غیر دات نت (Unmanaged Export) :
1) اول نوع پروژه رو Class Library انتخاب کنین (پروژه ی Class Library Portable انگار بخاطر اینکه نمیتونه Unmanaged Exports رو نصب کنه (البته برای من) پیشنهاد نمیشه)
2) بعد از منوی Project ، گزینه ی آخر رو انتخاب کنین (گزینه ی آخر ، نام پروژه و در ادامه اش کلمه ی properties داره) و در سربرگ دوم که Build هست برین و گزینه ی platform target (در وسط این سربرگ) و گزینه ی target (در بالای این سربرگ) رو روی X86 بزارین (چون اتوپلی ، نرم افزار 32 بیتی هست) و کلا به هیچ وجه نباید موقع Unmanaged Export ، روی حالتی غیر از x86 یا x86 که حالا بسته به نوع نرم افزار مقصدتون که چند بیتی رو ساپورت میکنه باشه (یعنی به هیچ وجه نباید روی any cpu تنظیم شده باشن که بصورت پیش فرض هستن و باید تغییر داد همونطور که گفته شد). البته من برای اطمینان ، علاوه بر اینها ، گزینه ای کنار گزینه ی start (که برای اجرا و کمپایل نرم افزار این دکمه ی استارت رو میزنیم) وجود داره که بصورت combo box هست که من از گزینه ی آخر اون combo box ، گزینه ی configuration رو میزنم و از اونجا هم گزینه ی any cpu رو به x86 تغییر میدم
3) بعد تابع تونو بنویسین ( دقت کنین تابع باید از نوع public static باشه تا بدون ایجاد شی و از هر جا بتونه فراخونی بشه) . دقت کنین احتمالا بیشتر از یک تابع و همچین توابع overloade هم نمیشه برای یه کلاس نوشت در حالت Unmanaged Export (توی یه منبع انگلیسی نوشته بود که بصورت بازگشتی هم نمیشه این نوع تابع ای که مینویسیم رو داخل سی شارپ فراخونی کرد و نوشت ولی اینا رو تست نکردم)
4) در منوی Tools ، گزینه ی NuGet Package Manager و بعد زیر منوی Package Manager Console رو انتخاب کنین و کد زیر رو در پنجره ی باز شده (پنجره ی Package Manager Console بنویسین) . البته قبل از نوشتن کد زیر ، مطمئن بشین که ویژال استودیو به اینترنت دسترسی داره :
حالا فایل های مورد نیاز برای Unmanaged Exports رو دانلود میکنه (آخرش باید پیام Successfully بده)کد:Install-Package UnmanagedExports
5) بعد از دانلود موفقیت آمیز ، فضای نام زیر رو به پروژه تون اضافه کنین :
بعد در بالای تابعی که نوشتین ، یه کلوشه باز کنین و در اونجا باید با تابع DllExport ، نام export و همچنین نوع export تون رو بنویسین . نام export تون باید هم نام تابع تون باشه و بصورت یه رشته ، در اولین آرگومان تابع DllExport (که در کلوشه ی بالای نام تابع مینویسین) ، بنویسین . در آرگومان دوم تابع DllExport ، نوع export که اغلب پیشنهاد میشه stdcall رو انتخاب کنین ، بنویسین . به این ترتیب که پروپرتی ای بنام CallingConvention (دقت کنین که در این پروپرتی ، حروف C ، بصورت حروف بزرگ هستند و باید این طوری بنویسین . یک حالت دیگه ی callingConvention بصورت کمل کیس هست که بعدش براتون علامت دو نقل قول میاره که این حالت منظور نیست) رو بنویسین و بعدش علامت مساوی بزارین (=) (البته خود اینتل لایسنس ویژال استودیو براتون میاره) و بعدش در فضای نام System.Runtime.InteropServices (این فضای نام رو بنویسین) و نقطه بزارین و enum ای بنام CallingConvention رو بنویسین (تا اینجا رو بازم خود اینتل لایسنس ویژال استودیو براتون میاره) و بعدش نقطه و بعدش متغییر که همون نوع خروجی مورد نظرتون هست را انتخاب کنین که اغلب نوع stdcall رو انتخاب میکنن برای unmanagedکد:using RGiesecke.DllExport;
یعنی به این صورت بنویسین :
کد:[DllExport("MyFunc", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
یه نمونه تابع کوچیک که دو تا عدد رو میگیره و جمع شونو برمیگردونه در سی شارپ که بصورت Unmanaged Export خروجی گرفته شد (البته اول ، نکاتی که گفته شد یعنی از نکته ی 1 تا 4 باید انجام بشه) :
کد:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using RGiesecke.DllExport; namespace ClassLibrary2 { public class Class1 { [DllExport("MyFunc", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)] public static int MyFunc(int a, int b) { return a + b; } } }
در مثال بالا ، به فضای نام RGiesecke.DllExport که اضافه شد و تابع DllExport که در بالای تابعی که نوشتیم (در بالای تابع MyFunc که نوشتیم) که در علامت کلوشه [] هست و آرگومان اول این تابع که نام Export مون که رشته ای هم نام تابع مون هست و همینطور آرگومان دوم این تابع رو دقت کنین)
حالا در اتوپلی برای فراخونی این تابع ، این کد رو بدین (البته در آرگومان اول تابع زیر در اتوپلی ، مسیر فایل dll تون که هر جا میزارید رو بدین) :
کد:result = DLL.CallFunction("AutoPlay\\Scripts\\ClassLibrary2.dll", "MyFunc", "5,10", DLL_RETURN_TYPE_INTEGER, DLL_CALL_STDCALL); Dialog.Message("Notice", result, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
راستی اینم بگم که Unmanaged Export هیچ ربطی به نسخه ی دات نت نداره و نسخه ی دات نت میتونه 4.5 و حتی بالاتر هم باشه
بعد دقت کنین چون پروژه رو بصورت x86 تولید کردین ، وقتی dll تون رو build کردین ، دیگه dll تون توی پوشه ی Debug ذخیره نمیشه . بلکه کنار پوشه ی Debug ، پوشه ای بنام x86 ساخته میشه که باز داخل خود همین پوشه ی x86 ، پوشه ی Debug ساخته میشه که dll تون داخل این پوشه قرار میگیره
6) تذکر : اتوپلی با تابع Dll.CallbackFunction اش فقط مقدار عدد و رشته رو میتونه به تابع داخل فایل dll بفرسته و دریافت کنه.
هر چیز دیگه ای بجز این در تابع مون (در dll) برگردونده شه مثل کل آرایه برگردونده شه (عضو خاصی از آرایه که عدد یا رشته رو برگردونه منظورم نیست) ، برنامه اتوپلی (اتوران) ، کرش میکنه
سعی کنید بولین هم ارسال نکنید ولی اشکالی نداره خروجی تابع تون در dll ، بولین برگردونه
مقدار بازگشتی تابع مون (در dll) اگه void بود ، در چهارمین آرگومان تابع DLL.CallFunction مون باید مقدار DLL_RETURN_TYPE_LONG رو انتخاب کنیم وگرنه نوع چیزی رو که برمیگردونه رو باید در چهارمین آرگومان این تابع انتخاب کنیم
باز هم یه تشکر گسترده از استاد علی کنم . خیلی ممنون استاد علی
Bookmarks