نحوه ی ساخت dll در سی شارپ برای زبان های غیر دات نت

SajjadKhati

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

http://barnamenevis.org/showthread....ن-C-Netدر-دلفی&p=627917&viewfull=1#post627917

این ابزار برای همه ی زبان های دات نت جواب میده؟ : .NET Assembly Import and Export Wizards for Delphi
من کار کردن باهاش رو بلد نیستم . یکی توضیح میده؟
باز هم از جایی پرسیدم گفتن باید از mono استفاده کنم توی سی شارپ . نمیدونم mono چیه؟! و چجوری میشه ازش استفاد کرد
 

SajjadKhati

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

اولا برای ساخت dll (من برای لوا نسخه ی 5.1 که زبان اسکریپتی غیر دات نت هست میخوام) ، dll ای که میخوام بسازم باید از پروژه ی Class Library برم یا از پروژه ی Class Library (Portable) و کلا آیا این دو پروژه در سی شارپ فرقی دارن با هم؟
توی نکات ای که لینک دادین ، چند تا نکته بود :
اول اینکه معماری پردازنده رو روی x86 یا x64 بزارم (any cpu) نمیشه . حالا روی هر کدوم (برای زبان هدف ام) بزارم فرق داره یا نه؟ روی کدوم بزارم؟
نکته ی دومی انگار میگه نام export رو همون نام تابع ام بزارم . اول اینکه اصلا نام export رو کجا و چجوری مشخص میکنن؟ و دوم اینکه آیا توی این نوع خروجی ، میشه داخل یه کلاس ، چند تا تابع تعریف کرد؟
سوم اینکه گفتش شما نمیتونین export تون رو از نوع generic قرار بدین . این generic چی هست و چجوری نباید export رو از نوع generic قرار داد؟

سه نکته ی آخر Release Notes رو هم اصلا متوجه نشدم چی میگن
و اینم بگم خروجی stdcall در لوا قابل فراخونی هست
 

the_king

مدیرکل انجمن
سلام
من بارهای بار دنبال این گشتم که چجوری میشه توی سی شارپ dll ای نوشت که بشه در زبان های غیر دات نت فراخونی کرد که تا حالا به جواب نرسیدم
الان دنبال این مطلب گشتم ، این چیزا رو پیدا کردم :

http://barnamenevis.org/showthread....ن-C-Netدر-دلفی&p=627917&viewfull=1#post627917

این ابزار برای همه ی زبان های دات نت جواب میده؟ : .NET Assembly Import and Export Wizards for Delphi
من کار کردن باهاش رو بلد نیستم . یکی توضیح میده؟
باز هم از جایی پرسیدم گفتن باید از mono استفاده کنم توی سی شارپ . نمیدونم mono چیه؟! و چجوری میشه ازش استفاد کرد
در همه زبان ها که شاید نه ولی در #C و Visual Basic .Net و ++C جواب میده. اما به هر حال این اون چیزی نیست که شما می خواهید، در بعضی زبان ها مثل ویژوال بیسیک و ++C و دلفی می توانید از کلاس هایی که در DLL هستند
و با COM سازگار اند شیء بسازید، این ابزار برای اونجور موارد ئه.
Mono یک پیاده سازی رایگان و open source برای NET. ئه. دقیقا منطبق با NET. نیست ولی تا حد خیلی زیادی سازگار ئه. اگر بخواهید در سیستم عامل هایی بجز ویندوز مثل Linux کد نویسی کنید مناسبه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
در همه زبان ها که شاید نه ولی در #C و Visual Basic .Net و ++C جواب میده. اما به هر حال این اون چیزی نیست که شما می خواهید، در بعضی زبان ها مثل ویژوال بیسیک و ++C و دلفی می توانید از کلاس هایی که در DLL هستند
و با COM سازگار اند شیء بسازید، این ابزار برای اونجور موارد ئه.
Mono یک پیاده سازی رایگان و open source برای NET. ئه. دقیقا منطبق با NET. نیست ولی تا حد خیلی زیادی سازگار ئه. اگر بخواهید در سیستم عامل هایی بجز ویندوز مثل Linux کد نویسی کنید مناسبه.
ممنون آقا علی
شما کلا روشی نمیشناسید که بشه در سی شارپ خروجی های رو برای زبان های غیر دات نت (لوا نسخه 5.1) و بصورت stdcall خروجی گرفت dll رو ؟؟
شدن میشه . تک و توک دیدم این کار رو میکنن .
اون پست بالا (شماره 2 مو جواب میدین؟) لینک مربوط بهش هم اینه :

https://www.nuget.org/packages/UnmanagedExports
 

the_king

مدیرکل انجمن
چند تا سئوال درباره راهنمای Unmanaged Export دارم :

اولا برای ساخت dll (من برای لوا نسخه ی 5.1 که زبان اسکریپتی غیر دات نت هست میخوام) ، dll ای که میخوام بسازم باید از پروژه ی Class Library برم یا از پروژه ی Class Library (Portable) و کلا آیا این دو پروژه در سی شارپ فرقی دارن با هم؟
نوع Portable برای پروژه هایی بکار میره که در چندین پلتفرم متفاوت استفاده می شوند، برای پروژه هایی که فقط در ویندوز بکار میره کاربردی نداره. از جزئیات فنی تفاوت اش اطلاعی ندارم اما تاثیرش ظاهرا تغییراتی است که برای سایر پلتفرم ها قابل استفاده باشه.
اگه بخواهید پروژه ای بسازید که هم در ویندوز و هم در سیستم عامل دیگری مثا لینوکس (مثلا با Mono) کامپایل بشه بهتره که نوع Protable اش رو انتخاب کنید. البته هر زمانی که خواستید می توانید نوع پروژه رو با چند کلیک تغییر بدهید.


توی نکات ای که لینک دادین ، چند تا نکته بود :
اول اینکه معماری پردازنده رو روی x86 یا x64 بزارم (any cpu) نمیشه . حالا روی هر کدوم (برای زبان هدف ام) بزارم فرق داره یا نه؟ روی کدوم بزارم؟
نکته ی دومی انگار میگه نام export رو همون نام تابع ام بزارم . اول اینکه اصلا نام export رو کجا و چجوری مشخص میکنن؟ و دوم اینکه آیا توی این نوع خروجی ، میشه داخل یه کلاس ، چند تا تابع تعریف کرد؟
سوم اینکه گفتش شما نمیتونین export تون رو از نوع generic قرار بدین . این generic چی هست و چجوری نباید export رو از نوع generic قرار داد؟
قطعا فرق داره، تداخل در فراخوانی با دو تا مدل حافظه متفاوت باعث بروز خطا میشه. برنامه میزبان که از DLL استفاده می کنه اگه 32 بیتی باشه باید حتما از x86 استفاده کنید، چون مدل حافظه اش 32 بیتی ئه و با DLL ئه 64 بیتی کار نمی کنه.
اون DLL ای که Any CPU ئه روی ویندوز 64 بیتی اجرا بشه مدل حافظه 64 بیتی رو بکار می بره و روی ویندوز 32 بیتی مدل حافظه 32 بیتی.
کلا Export برای زبانی ئه که چنین قابلیتی رو داره، در #C همچین مشخصه استانداردی نیست، احتمالا یک مشخصه دست ساز رو قابل از تعریف متد اضافه می کنید.
generic نوع داده های مشخص و استاندارد زبان ئه، int و double و ... که کامپایلر بدونه با چه نوع داده استانداردی export اش کنه. منظورش اینه که از کلاس دست سازتون به عنوان نوع داده استفاده نکنید.


سه نکته ی آخر Release Notes رو هم اصلا متوجه نشدم چی میگن
و اینم بگم خروجی stdcall در لوا قابل فراخونی هست
اون Release Note توضیحاتی در مورد قابلیت ها و کیفیت کار شون ئه، چیزی از شما که کاربر اش هستید نمی خواد.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نوع Portable برای پروژه هایی بکار میره که در چندین پلتفرم متفاوت استفاده می شوند، برای پروژه هایی که فقط در ویندوز بکار میره کاربردی نداره. از جزئیات فنی تفاوت اش اطلاعی ندارم اما تاثیرش ظاهرا تغییراتی است که برای سایر پلتفرم ها قابل استفاده باشه.
اگه بخواهید پروژه ای بسازید که هم در ویندوز و هم در سیستم عامل دیگری مثا لینوکس (مثلا با Mono) کامپایل بشه بهتره که نوع Protable اش رو انتخاب کنید. البته هر زمانی که خواستید می توانید نوع پروژه رو با چند کلیک تغییر بدهید.


قطعا فرق داره، تداخل در فراخوانی با دو تا مدل حافظه متفاوت باعث بروز خطا میشه. برنامه میزبان که از DLL استفاده می کنه اگه 32 بیتی باشه باید حتما از x86 استفاده کنید، چون مدل حافظه اش 32 بیتی ئه و با DLL ئه 64 بیتی کار نمی کنه.
اون DLL ای که Any CPU ئه روی ویندوز 64 بیتی اجرا بشه مدل حافظه 64 بیتی رو بکار می بره و روی ویندوز 32 بیتی مدل حافظه 32 بیتی.
کلا Export برای زبانی ئه که چنین قابلیتی رو داره، در #C همچین مشخصه استانداردی نیست، احتمالا یک مشخصه دست ساز رو قابل از تعریف متد اضافه می کنید.
generic نوع داده های مشخص و استاندارد زبان ئه، int و double و ... که کامپایلر بدونه با چه نوع داده استانداردی export اش کنه. منظورش اینه که از کلاس دست سازتون به عنوان نوع داده استفاده نکنید.


اون Release Note توضیحاتی در مورد قابلیت ها و کیفیت کار شون ئه، چیزی از شما که کاربر اش هستید نمی خواد.

ممنون آقا علی
یه نمونه ی کوچیک با این کد رو مثال میزنین؟ (همین توضیحی که توی اون لینک هست)
من بیشتر اون قضیه ی دوم که نام export هست رو نفهمیدم
مثال هم اگه زحمت نیست ، یه مثال بسیار کوچیک (مثلا فقط تابعی که دو آرگومان رو بگیره و جمع شون رو برگردونه) باشه که زحمت تون زیاد نشه
کدی که تو همون سایت داد یعنی :

کد:
Install-Package UnmanagedExports
رو هم توی قسمت NuGet Package Manager>Package Manager Console رو میزنم ارور میده و دانلود نمیتونه کنه
من برای لوا میخوام و توی ویندوز . باز هم تفاوتی نداره انتخاب پروژه ی Portable و غیر Portable ؟ من Portable رو انتخاب کردم
چون اتوپلی 32 بیتی هه ، x86 رو انتخاب کردم
 

SajjadKhati

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

http://www.codeproject.com/Questions/791891/Csharp-unmanaged-DLL-Export-Import-in-Cplusplus

البته این شخص هم مشکل اش رو مطرح کرد ولی کد زیر رو گذاشت :

کد:
//UnmanagedExports.cs
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
 
namespace AddDll
{
   class MyAddDll
   {
      [DllExport("Add", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
      public static double Add(double a, double b)
      {
         return a + b;
      }
   }
}
نمیدونم چقدر به کار من شبیه هه ولی خط :

کد:
 [DllExport("Add", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
شو متوجه نشدم
روش export هم که توی پست بالا پرسیدم ، هنوز مبهمه برام
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
یوهو پیدا کردم بعد از یه قرن
خدایا شکرت
الان در پوست خودم گنجایش ندارم :green::green::green::green:
باز هم معنای إِن تَنصُرُوا اللَّهَ يَنصُركُم که امام خامنه ای گفت برام مجسم شد
استاد علی خیلی از راهنمایی تون ممنونم . واقعا لطف بزرگی کردین . دیگه هم لازم نیست وقتم رو روی زبان های دیگه برای ساخت dll برای زبان لوا صرف کنم :rose::rose::rose:

تجربه ی خودمو بگم تا فراموش نکردم


آموزش ساخت 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 بنویسین) . البته قبل از نوشتن کد زیر ، مطمئن بشین که ویژال استودیو به اینترنت دسترسی داره :

کد:
Install-Package UnmanagedExports
حالا فایل های مورد نیاز برای Unmanaged Exports رو دانلود میکنه (آخرش باید پیام Successfully بده)

5) بعد از دانلود موفقیت آمیز ، فضای نام زیر رو به پروژه تون اضافه کنین :

کد:
using RGiesecke.DllExport;
بعد در بالای تابعی که نوشتین ، یه کلوشه باز کنین و در اونجا باید با تابع DllExport ، نام export و همچنین نوع export تون رو بنویسین . نام export تون باید هم نام تابع تون باشه و بصورت یه رشته ، در اولین آرگومان تابع DllExport (که در کلوشه ی بالای نام تابع مینویسین) ، بنویسین . در آرگومان دوم تابع DllExport ، نوع export که اغلب پیشنهاد میشه stdcall رو انتخاب کنین ، بنویسین . به این ترتیب که پروپرتی ای بنام CallingConvention (دقت کنین که در این پروپرتی ، حروف C ، بصورت حروف بزرگ هستند و باید این طوری بنویسین . یک حالت دیگه ی callingConvention بصورت کمل کیس هست که بعدش براتون علامت دو نقل قول میاره که این حالت منظور نیست) رو بنویسین و بعدش علامت مساوی بزارین (=) (البته خود اینتل لایسنس ویژال استودیو براتون میاره) و بعدش در فضای نام System.Runtime.InteropServices (این فضای نام رو بنویسین) و نقطه بزارین و enum ای بنام CallingConvention رو بنویسین (تا اینجا رو بازم خود اینتل لایسنس ویژال استودیو براتون میاره) و بعدش نقطه و بعدش متغییر که همون نوع خروجی مورد نظرتون هست را انتخاب کنین که اغلب نوع stdcall رو انتخاب میکنن برای unmanaged
یعنی به این صورت بنویسین :

کد:
[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 رو انتخاب کنیم وگرنه نوع چیزی رو که برمیگردونه رو باید در چهارمین آرگومان این تابع انتخاب کنیم


باز هم یه تشکر گسترده از استاد علی کنم . خیلی ممنون استاد علی :rose:
 
آخرین ویرایش:

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
واقعا ازتون ممنونم آقا علی . خیلی کمک کردین و بزرگترین مشکلم که ساخت dll بود ، به نسبت زیادی حل شد
فقط این ساختار رو توی #C انگار تازه میبینم . یعنی چرا تابع DllExport رو در کد زیر ، توی علامت کلوشه [] گذاشتن؟!!! :

کد:
[DllExport("MyFunc", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
این چه ساختاری هه؟
تا جایی که من میدونم تابع ها در سی شارپ ، موقع فراخونی ، در متد (تابع) ، فراخونی میشه پس این چرا اولا بیرون و دوما داخل کلوشه فراخونی شد؟!!
 

the_king

مدیرکل انجمن
واقعا ازتون ممنونم آقا علی . خیلی کمک کردین و بزرگترین مشکلم که ساخت dll بود ، به نسبت زیادی حل شد
فقط این ساختار رو توی #C انگار تازه میبینم . یعنی چرا تابع DllExport رو در کد زیر ، توی علامت کلوشه [] گذاشتن؟!!! :

کد:
[DllExport("MyFunc", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
این چه ساختاری هه؟
تا جایی که من میدونم تابع ها در سی شارپ ، موقع فراخونی ، در متد (تابع) ، فراخونی میشه پس این چرا اولا بیرون و دوما داخل کلوشه فراخونی شد؟!!
Attribute ئه، تعاریفی مثلا متد و مشخصه می تونه یک یا چند Attribute داشته یاشه. Attribute یکجور کلاس ئه، فرزندان System.Attribute. در مورد Attribute در #C جستجو و مطالعه کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
استاد علی ، اگه بخوام برای اتوپلی یه کنترل بصری توسط دات نت درست کنم (جدای از بحث ثبت کردن پلاگین و ساخت پلاگین) ، این کنترلِ دات نت را اول باید بصورت کنترل activex ثبت کنم تا با اتوپلی که زبانش unmanaged هست بتونه کار کنه؟
وقتی کنترل بصری دات نت (مثلا button) رو بصورت کنترل activex ثبت کنم ، اون وقت این کنترل activex دیگه بصورت managed نخواهد بود و بصورت کنترل unmanaged هست؟ (کنترل activex ای بصورت managed میشه اصلا داشته باشیم؟)
 

the_king

مدیرکل انجمن
سلام
استاد علی ، اگه بخوام برای اتوپلی یه کنترل بصری توسط دات نت درست کنم (جدای از بحث ثبت کردن پلاگین و ساخت پلاگین) ، این کنترلِ دات نت را اول باید بصورت کنترل activex ثبت کنم تا با اتوپلی که زبانش unmanaged هست بتونه کار کنه؟

نه. ارتباط بین پلاگین و کنترل بصری شما مطرحه، نه اتوپلی و کنترل بصری شما. برای اتوپلی هیچ فرقی نخواهد کرد که کنترل با چه استانداری طراحی میشه، اتوپلی مدیریت پنجره رو به پلاگین میسپاره. نقشی در این قضیه نداره.
کنترل مورد نظر شما یک پنجره داره که از طریق پیام های پنجره میشه و انواع فرمان ها رو بهش داد و یا داده گرفت. مثل همون روشی که در ++C و سایر زبان های ویژوال که پایه ویژوال شون توابع API ئه با TextBox ها و سایر کنترل ها ارتباط برقرار می کنند. یعنی از این جهت الزامی برای ActiveX بودن نیست و ActiveX بودن هم مزیتی ایجاد نمی کنه. ActiveX برای محیطی مزیت ئه که ساختار COM رو مستقیم نشون میده و بکار میبره. برای محیطی مثل اتوپلی که همچین ویژگی ای نداره مشخصات COM و ActiveX بودنش به چه دردی می خوره؟
وقتی کنترل بصری دات نت (مثلا button) رو بصورت کنترل activex ثبت کنم ، اون وقت این کنترل activex دیگه بصورت managed نخواهد بود و بصورت کنترل unmanaged هست؟ (کنترل activex ای بصورت managed میشه اصلا داشته باشیم؟)
چیزی که می گید اصلا معنی نداره، کنترل طراحی شده در NET. که ساختار COM و ActiveX نداره که به عنوان کنترل ActiveX ثبتش کنید. مثل اینه که بگید درخت رو به عنوان پرنده ثبت کنم. که چی بشه؟ درخت که قابلیت پرواز پیدا نمی کنه. دو تا تکنولوژی و ساختار متفاوت دارند.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ممنون استاد علی
پس نمیشه کنترل دات نت را با ثیت در activex بصورت سازگار با unmanaged در آورد . من گفتم شاید با این روشی که در زیر گفتش بشه (که نمیشه) :

How do I create an ActiveX control (COM) in C#?

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


Hi mohsen,
in PropertyGrid class you can specify the target handle on which window the control should be created.
I think the property of class is called "Handle", but I just can't look into my source code because I'm in the office.
I don't know how it is at Ribbonbar. Maybe you can also set the target handle on ribbonbar.
If not, then there is a possibility to manually move the RibbonBar to another window with the API function SetPartent_().
Yes, I created the DLL file with Visual Studio 2017.

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

الان دوستم کد سی شارپ رو ازش گرفت ، با تابع setparent اضافه کرده بود
 
آخرین ویرایش:

the_king

مدیرکل انجمن
کلا دنبال یه روشی میگردم که بشه کنترل های دات نت را به پنجره های api پایه ، مثل اتوپلی اضافه کرد (البته میدونم با تابع setparent در api میشه ولی میخوام بدونم هیچ روشی نیست که از طریق استاندارد یعنی توسط هندل با هم ارتباط برقرار کنن؟)

توابع API رو بر اساس چه معیاری استاندارد یا غیر استاندارد میدونید؟ کل پنجره های ویندوز بر اساس همین API مدیریت میشه و لاغیر که همه شون بر اساس Handle هستند. شما کدوم توابع API مربوط به مدیریت پنجره رو دیدید که بر اساس Handle پنجره نباشه که بهش تاییدیه استاندارد ندادید؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
توابع API رو بر اساس چه معیاری استاندارد یا غیر استاندارد میدونید؟ کل پنجره های ویندوز بر اساس همین API مدیریت میشه و لاغیر که همه شون بر اساس Handle هستند. شما کدوم توابع API مربوط به مدیریت پنجره رو دیدید که بر اساس Handle پنجره نباشه که بهش تاییدیه استاندارد ندادید؟

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

the_king

مدیرکل انجمن
پس هیچ راهی برای ارتباط با پنجره ی اتوپلی و کنترل های دات نت وجود نداره همونطور که قبلا گفته بودین (مگر اینکه رابط شون توابع api ویندوز باشن)
ممنون
طبق معمول از اساس یک فرض اشتباه رو مبنا قرار میدید که یک حکم اشتباه رو نتیجه گیری کنید. انگار که پنجره اتوپلی با کنترل های غیر دات نت ارتباط دیگه ای میتونسته داشته باشه که بخاطر دات نت بودن نتونه داشته باشه. پنجره اتوپلی با شیء MediaPlayer چطور ارتباط برقرار می کنه؟ شما که به اتوپلی آشنا هستید نحوه ارتباطش رو بگید.
شما اون شی Windows Media Player رو که یک ActiveX ئه در ویژوال استدیو یا ویژوال بیسیک 6 یا هر محیط دیگه ای که اجزاء اش رو نشون میده بررسی کنید، ببینید اون متد ها و پروپرتی ها رو در اتوپلی میبینید؟ نه دیگه. نمی بینید. ببینید چقدر رخداد داره، چقدر تنظیمات داره، اون رخداد ها و تنظیمات رو داخل اتوپلی میبینید و بهشون دسترسی دارید؟ نه.
اتوپلی براش هیچ فرقی نمی کنه که این کنترل ActiveX ئه، Managed ئه یا Unmanaged ئه، با #C نوشته شده یا ++C یا جاوا و ... اتوپلی هیچ طریقه ارتباطی مستقیمی با کنترلی که از خارج محیط اش واردش شده نداره.
برای مساله شما هیچ فرقی نمی کرد که ویژوال استدیو کنترل های NET. بسازه یا ActiveX یا Java applet یا ... اصلا NET. و غیر NET. ای مطرح نیست. اتوپلی با هیچ کنترلی از هیچ پلتفرمی نمی تونه ارتباط مستقیم برقرار کنه و بدون پلاگین مناسب هم کارایی نداره. داخل پلاگین هم با انواع شیوه ها با کد نویسی ارتباط برقرار میشه، به انواع روش های دلخواه برنامه نویس.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
طبق معمول از اساس یک فرض اشتباه رو مبنا قرار میدید که یک حکم اشتباه رو نتیجه گیری کنید. انگار که پنجره اتوپلی با کنترل های غیر دات نت ارتباط دیگه ای میتونسته داشته باشه که بخاطر دات نت بودن نتونه داشته باشه. پنجره اتوپلی با شیء MediaPlayer چطور ارتباط برقرار می کنه؟ شما که به اتوپلی آشنا هستید نحوه ارتباطش رو بگید.
شما اون شی Windows Media Player رو که یک ActiveX ئه در ویژوال استدیو یا ویژوال بیسیک 6 یا هر محیط دیگه ای که اجزاء اش رو نشون میده بررسی کنید، ببینید اون متد ها و پروپرتی ها رو در اتوپلی میبینید؟ نه دیگه. نمی بینید. ببینید چقدر رخداد داره، چقدر تنظیمات داره، اون رخداد ها و تنظیمات رو داخل اتوپلی میبینید و بهشون دسترسی دارید؟ نه.
اتوپلی براش هیچ فرقی نمی کنه که این کنترل ActiveX ئه، Managed ئه یا Unmanaged ئه، با #C نوشته شده یا ++C یا جاوا و ... اتوپلی هیچ طریقه ارتباطی مستقیمی با کنترلی که از خارج محیط اش واردش شده نداره.
برای مساله شما هیچ فرقی نمی کرد که ویژوال استدیو کنترل های NET. بسازه یا ActiveX یا Java applet یا ... اصلا NET. و غیر NET. ای مطرح نیست. اتوپلی با هیچ کنترلی از هیچ پلتفرمی نمی تونه ارتباط مستقیم برقرار کنه و بدون پلاگین مناسب هم کارایی نداره. داخل پلاگین هم با انواع شیوه ها با کد نویسی ارتباط برقرار میشه، به انواع روش های دلخواه برنامه نویس.

بازم ممنون استاد علی
والا من کجا با اتوپلی آشنام! من اگه بلد بودم ، خودم مشکلم رو حل میکردم :)
ببینید من منظورم اینه که مثلا یک کنترل و پنجره ای رو که با تابع CreateWindowEx از تابع api ساخته بشه ، مثلا میشه هندل خروجی این تابع را گرفت و راحت با پنجره ی اتوپلی و با هندل ها و کنترل های دیگه ی اتوپلی باهاش در تماس بود
ولی برای مدیریت کنترل های دات نت ، صرفا با اعضای خود همون کنترل نمیشه به اتوپلی اضافه کرد و کار کرد . باید از تابع api ویندوز کمک گرفت
حالا متوجه شدم . ممنون
 

SajjadKhati

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

Nlua by NLua

یه تابع DoString داره که یه رشته به عنوان کدهای لوا میگیره . خروجی متغییرها و توابع و .. ای که داخل کد لوا (ورودی DoString) بکار برده شد هم توسط ایندکسر همون شی nlua (ایندکسر از نوع رشته که نام متغییرها و تابع و ... ی بکار برده شده در کدهای لوا هست) (با انجام تبدیل) ، در دسترس مون قرار میگیره . برای مقداردهی هم که راحت باز هم توسط همین ایندکسر، هر شی از سی شارپ را توش میشه ریخت
یه مثال :


کد:
            using (Lua lua = new Lua())
            {
                lua.DoString(@"
                x=101;
                y = 'salam'
                ");
                MessageBox.Show(((double)lua["x"]).ToString() + "\n" + ((string)lua["y"]));
                lua["x"] = new Form(); // مقدار متغییر x در لوا ، از نوع عدد به نوع Form تغییر کرد
            }

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

the_king

مدیرکل انجمن
سلامی مجدد استاد علی
اول اینکه اون موقع میگفتم که توی سی شارپ چجوری میشه از لوا استفاده کرد ، با nlua میشه (اون موقع نمیدونستم چجوری کار میکنه ولی خیلی آسونه) :) :

Nlua by NLua

یه تابع DoString داره که یه رشته به عنوان کدهای لوا میگیره . خروجی متغییرها و توابع و .. ای که داخل کد لوا (ورودی DoString) بکار برده شد هم توسط ایندکسر همون شی nlua (ایندکسر از نوع رشته که نام متغییرها و تابع و ... ی بکار برده شده در کدهای لوا هست) (با انجام تبدیل) ، در دسترس مون قرار میگیره . برای مقداردهی هم که راحت باز هم توسط همین ایندکسر، هر شی از سی شارپ را توش میشه ریخت
یه مثال :


کد:
            using (Lua lua = new Lua())
            {
                lua.DoString(@"
                x=101;
                y = 'salam'
                ");
                MessageBox.Show(((double)lua["x"]).ToString() + "\n" + ((string)lua["y"]));
                lua["x"] = new Form(); // مقدار متغییر x در لوا ، از نوع عدد به نوع Form تغییر کرد
            }

خوب حالا میخوام کدهای اتوپلی را به عنوان رشته به تابع DoString بدم . تا اینجا مشکلی نیست . ولی مشکل اینجاست که اتوپلی ، توابع و اشیاء مخصوص خودش را داره دیگه . مثلا تابع Dialog.Message در اتوپلی شناخته شده هست . اگه این تابع را در ورودی تابع DoString ، خوب زمان اجرا ، تابع Dialog.Message را نمیشناسه (چون توی اتوپلی تعریف شده هست)
حالا سئوالم اینه که آیا روشی هست که وقتی مثلا تابع Dialog.Message در تابع DoString بکار برده شد ، جوری بشه که انگار در اتوپلی اجرا میشه یعنی توابع و کنترل های ثبت شده ی در اتوپلی را اجرا کنه؟
این قابلیتی بوده که باید در اتوپلی پیدا میکردید، سوا از بحث این nlua. شما اگر بتوانید در #C کد اتوپلی رو اجرا کنید که اصلا نیازی به nlua ندارید. اگر هم نتوانید nlua هم نمیتونه.
شما یک مفسر برای لوا پیدا کردید، اما مفسر اتوپلی نیست. در بعضی مفسر ها این امکان هست که در زمان اجرا برای هر مورد ناشناخته مثل همون Dialog یک رخداد یا متد فیدبک ایجاد کنه، یعنی درجا با مشاهده یک مورد ناشناخته بجای اینکه خطا بده به کد شما درخواستی بده تا کد شما بتونه بر اساس اون عبارت ناشناخته عملیاتی رو انجام بده، یعنی فرضا اگه مفسر براش تابع Sin معنی نداشته باشه، خودتون عملیات محاسباتی Sin رو پیاده سازی کنید و روال تفسیر ادامه پیدا کنه. ولی در این مورد حتی اگه این کتابخانه همچین قابلیتی هم داشت بدرد شما نمیخورد، چون شما در #C مفسر اتوپلی ندارید. فقط می توانستید یک MessageBox ای شبیه اش رو با #C پیاده سازی کنید. چیزی که شما در مورد اشیاء اتوپلی میخواهید باید جزو قابلیت های خروجی اتوپلی باشه که قاعدتا نیست چون اتوپلی کتابخانه که نیست بیارید از متد هاش در برنامه تون فراخوانی شون کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
این قابلیتی بوده که باید در اتوپلی پیدا میکردید، سوا از بحث این nlua. شما اگر بتوانید در #C کد اتوپلی رو اجرا کنید که اصلا نیازی به nlua ندارید. اگر هم نتوانید nlua هم نمیتونه.
شما یک مفسر برای لوا پیدا کردید، اما مفسر اتوپلی نیست. در بعضی مفسر ها این امکان هست که در زمان اجرا برای هر مورد ناشناخته مثل همون Dialog یک رخداد یا متد فیدبک ایجاد کنه، یعنی درجا با مشاهده یک مورد ناشناخته بجای اینکه خطا بده به کد شما درخواستی بده تا کد شما بتونه بر اساس اون عبارت ناشناخته عملیاتی رو انجام بده، یعنی فرضا اگه مفسر براش تابع Sin معنی نداشته باشه، خودتون عملیات محاسباتی Sin رو پیاده سازی کنید و روال تفسیر ادامه پیدا کنه. ولی در این مورد حتی اگه این کتابخانه همچین قابلیتی هم داشت بدرد شما نمیخورد، چون شما در #C مفسر اتوپلی ندارید. فقط می توانستید یک MessageBox ای شبیه اش رو با #C پیاده سازی کنید. چیزی که شما در مورد اشیاء اتوپلی میخواهید باید جزو قابلیت های خروجی اتوپلی باشه که قاعدتا نیست چون اتوپلی کتابخانه که نیست بیارید از متد هاش در برنامه تون فراخوانی شون کنید.

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

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

بالا