PDA

نسخه کامل مشاهده نسخه کامل : روش load کردن dll ؟



cpplover
16-01-2008, 12:22
دوستان محترم :

میخواستم بدونم چطوری میشه در visual c++ 2005 یک dll رو load کرد و از توابعش استفاده کرد ؟
مثلا این dll تابعی به نام miladi2shamsi داره که عمل تبدیل تاریخ رو انجام میده
فقط میخواستم روش بارگذاری این dll رو به صورت مختصر توضیح بدید.
با تشکر

m3hrz4d
16-01-2008, 17:49
شما فایل lib. و h. ی از DLL دارین؟ نداشتن lib. مساله ای نداره ولی اگه header ی ندارین باید تعریف کامل توابعی که میخواهین استفاده کنین رو داشته باشین.

cpplover
16-01-2008, 19:10
سلام دوست عزیز

نه فایل .lib و نه .h هیچکدوم رو ندارم .
ببینید این dll رو که میگم همون dll معروف shamsi.dll هست که از آدرس زیر به همراه help کامل دریافتش کردم :



[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])



من سعی کردم از روشهایی واسه بارگذاری این dll استفاده کنم اما حتی با اینکه در برنامه خطایی وجود نداشت درست عمل نکرد (ضمنا من dll رو رجیستر هم کردم و اون رو در پوشه سیستم هم قرار دادم)

حالا من روش کارم رو واسه شما توضیح میدم اگه در بعضی جاها کارهای عجیب غریبی کردم من رو ببخشید و به من نخندید چون این تجربه اولم بود !:20:

ابتدا یک دستگیره برای فراخوانی dll تعریف کردم :



HINSTANCE dastgire;



در ادامه سعی کردم تابع Miladi2Shamsi مربوط به dll رو تعریف کنم : یعنی نوع متغیری به نام MILADI2SHAMSI را تعریف کردم که آدرس تابعی را نگهداری می کند که از نوع CString را برمی گرداند و پارامتری از نوع CString دارد دستور بعدی هم متغیری به نام Miladi2Shamsi و از نوع MILADI2SHAMSI تعریف کردم. این کد ها را در فایل Dlg.cpp برنامه قرار دادم :


typedef CString(*MILADI2SHAMSI)(CString);

MILADI2SHAMSI Miladi2Shamsi;





در OnInitDialog هم کدهای زیر رو نوشتم :


dastgire=LoadLibrary(_T("shamsi.DLL"));

Miladi2Shamsi=(MILADI2SHAMSI)GetProcAddress(dastgi re,"MILADI2SHAMSI");



یک دکمه و دو Edit text با متغیر هایی از نوع cstring به نامهای shams و milad تعریف کردم و کدهای زیر رو در تابع دکمه قرار دادم :


UpdateData();
shams=Miladi2Shamsi(milad);

UpdateData(FALSE);
اما در نهایت جواب نگرفتم. میشه یک راهکار درست و حسابی بگید و بگید که اصلا کارهایی رو که من انجام دادم درست هستند یا نه ؟

با تشکر

m3hrz4d
16-01-2008, 21:05
این DLL یک ActiveX DLL هست نه یک DLL معمولی که مجموعه ای از توابع باشه بنابراین شما اصلا نمیتونین با توابع LoadLibrary و GetProcAddress باش کار کنین.

این یک نمونه کد واسه استفاده ازش.ضمن اینکه شما اینجا برای مقادیر رشته ای با bstr_t_ و یا BSTR کار دارین نه با CString.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

گرچه در کل به نظر من بهتره از الگوریتم ها و کد هایی که برای تبدیل تاریخ میلادی به شمسی هست استفاده کنین بجای استفاده از یک ActiveX

cpplover
16-01-2008, 23:15
با سلام مجدد

دست شما درد نکنه m3hrz4d عزیز

کد شما خیلی خوب جواب داد اما من دو تا کار روش انجام دادم :

اول اینکه main رو برداشتم و بعدش اینکه NULL در messagebox ها رو حذف کردم
(کار null ) در اینجا دقیقا چیه ؟
بعد هم اگه ممکنه در مورد bstr_t_ و یا BSTR که گفته بودید وبقیه خطوط توضیحی بدید ممنون میشم
ضمنا در مورد توابعی که ورودی می گرفتند دچار مشکل شدم (مثل miladi2shamsi ) مثلا میخواستم در یک edit text تاریخ میلادی رو بدم و شمسی رو در edit دیگری دریافت کنم؟
در مورد الگوریتم های دیگه هم که گفته بودید من قبلا خیلی گشته بودم ولی خطاهایی داشتند و دقیق نبودند ولی اگه شما الگوریتم دقیقی دارید ما رو بی اطلاع نگذارید (حتی میلادی به قمری)
ببخشید اینقدر حرف زدم (نوشتم)
با تشکر

m3hrz4d
17-01-2008, 04:40
برنامه ای که من کدش رو دادم در قالب یک Console Application بود(واسه راحتی کار) و Main هم برای همین بود. توی MFC ننوشتم.
این MessageBox ی که توی کد من هست API ویندوز هست و پارامتر اولش هندل Window یه که پیغام تحتش نشون داده میشه(و میتونه 0 یا همون NULL باشه و اصلا مقدار دهی نشه).
ولی شما وقتی در حالت معمولی توی MFC این تابع رو صدا میزنین در اصل متد یک کلاس(مثل CDialog ) رو صدا میزنین و اون متد دیگه نیازی به این هندل نداره و هندل رو از خود شی میگیره...
-
BSTR یه Data Type برای نوع رشته هست که متن یونیکد رو نگه میداره و علاوه بر اون چهار بایت هم برای طول رشته در نظر میگیره و واسه کار کردن باهاش باید با توابعی مثل SysAllocString و SysFreeString کار کرد.
توضیحات کامل تو MDSN هست :
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

bstr_t_ یک کلاس برای کار کردن با BSTR هست که کارای Allocation و Deallocation رو انجام میده و برای استفاده دیگه نیازی به توابع SysAllocString و امثال اینا نیست و تا اونجایی که میدونم رشته ها توی COM هم بر اساس همین bstr_t_ هستن.

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ](VS.71).aspx

توابع وروی این DLL هم اون هایی که توی Visual Basic باید داده ی Date داد اینجا باید داده ی *BSTR یعنی یه Pointer به یک BSTR که حاوی رشته ی تاریخ مورد نظرتونه بهشون داد.ضمن اینکه شما با استفاده از متد GetBSTR میتونین BSTR مربوط به یک bstr_t_ رو بگیرین بنابراین نیازی نیست که مستقیما از BSTR استفاده کنین.

توی این کد هم ما بعد از Initialise کردن COM , یک پونتر به شی از کلاسی که توی DLL هست تعریف میکنیم و با دادن اسم کلاس به CreateInstance یک شی(یک Instance از شی) از اون کلاس ایجاد میکنیم. بعد از Initialise شدن, میتونیم از متد های اون کلاس استفاده کنیم.
در آخر هم کار Release کردن اون Instance رو انجام میدیم.
-
برای کاری که میخواهین بکنین این کد رو نوشتم.فقط توجه کنین که برای اینکه کل کد یکجا باشه اینطوری نوشتم وگرنه شما میتونین یک عضو کلاس بجای ShamsiPtr تعریف کنین و تابع CoInitialise و مقدار دهی ShamsiPtr رو در قسمت OnInitDialog (یا توابع مشابه) و قسمت Release و CoUninitialise رو در قسمت OnDestory قرار بدید.منظورم اینه که نباید برای هر بار انجام تبدیل شما یکبار Com رو Initialise و Uninitialise کنین:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
یک Buffer تعریف کردم و متن Edit ی که حاوی تاریخ میلادی (با فرمت yyyy-mm-dd )هست رو ریختم داخلش (با GetDlgItemText) و از اون بافر یک bstr_t_ ساختم به این خاطر که ما باید به تابع تبدیل که تاریخ رو میخواد یک BSTR* بدیم نه یک رشته به سبک زبان C.
بعد هم متد مورد نظر تبدیل تاریخ رو صدا زدم و با استفاده از متد GetBSTR همونطور که گفتم BSTR مربوط به bstr_t_ رو گرفتم و پوینترش رو به تابع دادم(میشد بجای bstr_t_ مستقیما یک BSTR تعریف کرد و از تابع SysAllocString برای مقدار دهیش استفاده کرد منتها من برای راحتی کار یک bstr_t_ تعریف کردم) و بعد هم خروجی متد که یک bstr_t_ هست رو به edit دوم اختصاص دادم.(کلاس bstr_t_یک operator تبدیل به wchar_t* و *char داره به همین دلیل بدون هیچ تبدیلی میشه اون رو به تابع SetDlgItemText داد)

کد تبدیل تاریخ هم من توی این فروم ها زیاد دیدم منتها توی ++C تاحالا احتیاج پیدا نکردم واسه همین هیچ کدوم رو امتحان کردم.

someone
17-01-2008, 08:38
سلام!

M3hrz4d کامل توضیحات رو دادن ، اما روش دیگه ای هم وجود داره.


با توجه به اینکه این Dll یک ActiveX DLL هست می تونین از با استفاد از CLR یک Wrapper براش
ایجاد کنین. ترکیبی از ManagedCode و UnmanagedCode
به چنین برنامه هایی mixed Application میگن.




خب! شروع می کنیم!

1-

از منوی Project گزینه Properties رو انتخاب کنین . (که معمولا اسم پزوژه + Properties هست)
از پنجره باز شده با توجه به تصویر زیر تغییرات لازم رو انجام بدین.
یعنی Common Language Runtime Support رو روی Common Language Runtime Support (/clr)i
قرار بدین.


[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]


2-

در همین پنجره اینبار روی CommonProperties کلیک کنین و با توجه به تصویری
که براتون گذاشتم مراحل رو دنبال کنین تا Shamsi.dll به برنامه اضافه بشه.
در نهایت تمامی تغییرات رو Apply کنین.



[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]


3-

الان اگه به ClassView مراجعه کنین متود های کلاس مورد نظر رو میبینین.


[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]



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

کد زیر رو بعد از تعریف Header ها قرار بدین :


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


و کد زیر رو مثلا در تابع OnInitDialog قرار بدین :


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


میبینین که در اینجا نیازی به CoInitialize و غیره نیست.
در مورد استفاده از توابع هم که دوستمون کاملا توضیح دادن.
راستی لینک مربوط به bstr_t_ مربوط به VC2003 هست که در مورد نسخه 8.0 اون
به لینک زیر مراجعه کنین :
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ](VS.80).aspx



موفق باشین.

cpplover
17-01-2008, 21:59
از جوابهای شما کمال تشکر رو دارم :

Someone عزیز روش شما خیلی کامل و کوتاه بود آیا واسه توابعی که مقدار ورودی می گیرند باید از روش دوستمون m3hrz4d استفاده کنیم ؟(همون مطالب BSTR )

m3hrz4d عزیز در کد شما در قسمت تعریف MAX_LENGTH دچار خطای زیر شد :



missing type specifier - int assumed. Note: C++ does not support default-int



آیا بعد از const نباید نوع هم ذکر شود ؟

با تشکر

m3hrz4d
17-01-2008, 22:56
چرا, نوع هم میخواد یادم رفت بگذارم.

someone
18-01-2008, 02:54
خب! یه مقدار از اینجا به بعد قضیه فرق میکنه!
برنامه ی ما معروف به Mixed هست!

در آرگومان توابعی که با این روش وارد شدن باید از نوع معرفی شده توسط CLR باشن.
مثلا در مورد Miladi2Shamsi اگه به ClassView مراجعه کنین ، می بینین که آرگومانش از نوع ^String
هست. این نوع داده در C++.Net استفاده میشه. و تقریبا مشابه CString هست اما با فرق هایی.

به عنوان مثال :


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

cpplover
18-01-2008, 20:10
با سلام

میخوام بدونم مگه وقتی از (" ") در برنامه استفاده کردید اون داده مگه string نیست ؟ اگه جواب مثبته پس چرا نمیشه با به کار بردن متغیر edit boxدر اینجا هر داده ای رو وارد کرد ؟

someone
19-01-2008, 01:44
بله! جواب مثبته!
ولی String با CString تفاوت داره. (دقت کنین که System::String و string هم ، با یکدیگه تفاوت دارن. )
String یک نوع داده برای نگهداری رشته هاست اما در Net.
CString هم چنین کاری انجام میده اما در MFC
با توجه به Constructor کلاس CString ، میتونین داده ها از نوع String رو استخراج کنین. بدون فراخوانی
مستقیم اون. اما برای تبدیل نوع CString به String باید از Constructor کلاس String استفاده کنین.
در این صورت میتونین داده ها رو از editBox مستقیما بخونین :

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

به جای myData میتونین اسم متغییر editBox رو بذارین.

cpplover
20-01-2008, 09:44
متشکرم



انصافا در این تایپیک خیلی چیز جدید یاد گرفتم

از هر دو دوست خوبم تشکر می کنم .

immortality
03-11-2009, 18:50
سلام
برای لود کردن dll شامل چند تا تابع در visual c++ 2006 چطور باید عمل کرد؟
ممنون

djsohrab2007
09-03-2011, 13:24
سلام

من خیلی دوست دارم کار با dll ها را یاد بگیرم ولی نه به صورت حفظی ، یعنی هر خط که می نویسم را بفهم چی کار می کنه.

مثلا وقتی مینویسم
int a
یعنی یک متغیر به نام a که قرار است توش عدد صحیح بریزیم ، تعریف می کنیم.

ولی وقتی کدهای شما را در پست های قبل دیدم دقیقا نمی دونم چه کار می کنند ، اما با این حال وقتی می خوام از dll استفاده کنم اونها را کپی می کنم و کمی تغییر میدم تا کار کنه ! ( کاری که اصلا دوست ندارم :37: )

لطفا وقت بگذارید و کامل از ابتدا توضیح دهید

با تشکر از شما دوستان:11:

djsohrab2007
10-03-2011, 11:26
اگر جواب بدید ثواب داره ها !:40:

یکی نیست بخواد به من یاد بده چه طوری با dll کار کنم:18:

djsohrab2007
30-03-2011, 10:24
سلام آقا جواب بدی ثواب داره ها