PDA

View Full Version : فراخوانی function از یک DLL



ir_programmer
پنج شنبه 12 مهر 1386, 09:01 صبح
یک فایل dll به نام SmartRD.dll دارم. می دونم که داخل اون یه function به نام SCConnect وجود داره.

اون dll رو تو شاخه جاری پروژم گذاشتم و کد زیر رو برای فراخوانی اون نوشتم. اما error میده!

کدم اینه و خطای اونو گذاشتم.

خطا :


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TSCConnect = function():Boolean;
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
DLLInstance : THandle;
SCConnect : TSCConnect;
begin
{ Load the DLL. }
DLLInstance := LoadLibrary('SmartRD.dll');
{ Get the address of the procedure. }
@SCConnect := GetProcAddress(DLLInstance, 'SCConnect');
{ Call the procedure. }
SCConnect();
{ Unload the DLL. }
FreeLibrary(DLLInstance);
end;

end.

mohssen_mz
پنج شنبه 12 مهر 1386, 10:24 صبح
چرا به صورت داینامیک dll وتوابع را فراخوانی نمیکنی

function funnam (param):outpu result
External 'namedll';

البته بعد از این قسمت تو کد ادیتور
{$R *.dfm}

ir_programmer
پنج شنبه 12 مهر 1386, 10:53 صبح
اگه منظورت اینه بازم error میده:
error رو ضمیمه کردم.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function SCConnect(): Boolean; external 'smartrd.dll';
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
SCConnect;
end;

end.

vcldeveloper
پنج شنبه 12 مهر 1386, 13:53 عصر
چرا به صورت داینامیک dll وتوابع را فراخوانی نمیکنی
اونی که شما نوشتید فراخوانی Dynamic نیست، بلکه Static هست. یعنی DLL همزمان با اجرای برنامه در فضای آدرس دهی پروسس لود می شود و تا پایان اجرای برنامه در حافظه باقی می ماند.
روشی که کاربر سوال کننده استفاده کردند، فراخوانی Dynamic هست که در آن ابتدا DLL در زمانی که بهش احتیاج است در حافظه لود میشه، بعد از آن تابع مربوطه فراخوانی میشه و در نهایت DLL از حافظه خارج میشه.
البته این دوستمون کد خیلی جالبی ننوشته، چون نه لود شدن DLL در حافظه را چک می کند، نه وجود تابع در DLL را، همچنین، Unload کردن DLL هم در بلوک try/finally قرار نداره که حتما DLL تحت هر شرایطی Unload بشه.
برای مشکلی که بهش اشاره کردید، احتمال داره که DLL مربوطه در حافظه لود نشده باشه، تابع مربوطه در DLL وجود نداشته باشه، Signature تابع با اون چیزی که شما نوشتید متفاوت باشه و دلایل دیگه.
بهتره کلمه DLL را در بخش دلفی سایت جستجو کنید.

sh
پنج شنبه 12 مهر 1386, 20:51 عصر
من قبلا دیده بودم که چند نفر برنامه نویس زبان دلفی نتونسته بودند از این Dll استفاده کنن و برنامه را با VB 6 نوشتند

ir_programmer
شنبه 14 مهر 1386, 08:14 صبح
من قبلا دیده بودم که چند نفر برنامه نویس زبان دلفی نتونسته بودند از این Dll استفاده کنن و برنامه را با VB 6 نوشتند

برنامه حمل و نقل من دلفیه.
واسه خوندن اطلاعات از Smart Card چیکار کنم. آخه یعنی همه برنامه رو باید ببرم تو VB???!!!

ir_programmer
چهارشنبه 16 آبان 1386, 16:27 عصر
تمام کسانی که با برنامه saba :ار کردن کمکم کنن!

barnamenevisforme
دوشنبه 15 اسفند 1390, 22:12 عصر
سلام
لینک فایل اینجاست.
در مورد رجیسترش هم هر کی خواست از خودم بپرسه.
http://www.iranled.com/forum/thread-23013.html

barnamenevisforme
سه شنبه 16 اسفند 1390, 09:30 صبح
واسه اطمینان از سالم بودن فایل این لینک رو چک کنید.
http://www.prevx.com/filenames/X3028840097985773917-X1/SMARTRD.DLL.html

barnamenevisforme
دوشنبه 22 اسفند 1390, 08:31 صبح
با سلام
یکی از دوستان به من بگه فرق exported function با com method توی تعریف زیر چیه؟
Function Name : DllGetClassObject
Type : Exported Function
==================================================
Function Name : DllRegisterServer
Type : Exported Function
==================================================
Function Name : IAcs38RD::SCConnect
Type : COM Method
وقتی من تابع IAcs38RD::SCConnect رو فراخونی میکنم خطای there is no entery point میده.

vcldeveloper
پنج شنبه 25 اسفند 1390, 13:46 عصر
یکی از دوستان به من بگه فرق exported function با com method توی تعریف زیر چیه؟
exported function ها همون توابع معمولی هستند با لود کردن DLL و فراخوانی تابع، می تونید ازشون استفاده کنید.
اونی که نوشته COM Method، تابع معمولی نیست، بلکه متد یک کلاس COM هست. برای استفاده ازش هم باید Type Library اون کلاس COM خاص را Import یا خودتو به صورت داینامیک یک شی از اون کلاس بسازید، و ازش استفاده کنید. COM یک تکنولوژی انحصاری مایکروسافت هست که می تونید با جستجوی عبارت MS COM درباره اش مطالعه کنید.

اون DLL شما دو تابع معمولی برای رجیستر کردن و Unregister کردن کلاس COM مربوطه داره، و مابقی توابع اش متدهای COM هستند.

barnamenevisforme
جمعه 26 اسفند 1390, 09:03 صبح
سلام
استاد گرامی منظورتون اینه که توابعی که از نوع com معرفی شدن مختص یک dll و یا کتابخونه ی دیگه هستن که باید توی تعریف تابع اسم اون رو قید کنم.درسته؟
اگه یه مثال بزنید و یا توضیح بیشتری بدید ازتون ممنون میشم.اگرچه تا همین مرحله هم از شما متشکرم.

vcldeveloper
جمعه 26 اسفند 1390, 12:19 عصر
منظورتون اینه که توابعی که از نوع com معرفی شدن مختص یک dll و یا کتابخونه ی دیگه هستن که باید توی تعریف تابع اسم اون رو قید کنم.درسته؟
COM یک تکنولوژی انحصاری مربوط به مایکروسافت هست که به صورت مستقل از زبان برنامه نویسی عمل میکنه، و به برنامه نویس این امکان رو میده که یک رابط برنامه نویسی شی گرا برای تمام یا بخشی از برنامه خودش ایجاد کنه، به طوری که اون بخش از طریق سایر برنامه های موجود بر روی آن سیستم، و یا حتی خارج از اون سیستم (DCOM) قابل دسترس و استفاده باشه. در واقع با استفاده از COM شما می تونید برنامه خودتان را به کامپوننت هایی تقسیم کنید که هر کدام بر روی همین سیستم یا سایر سیستم های موجود در شبکه نصب شده اند، و فارغ از اینکه با چه زبان برنامه نویسی نوشته شدند، در دسترس سایر بخش های برنامه شما، یا سایر برنامه های موجود بر روی سیستم هستند. عمده استفاده کننده COM خودِ مایکروسافت هست. بسیاری از تکنولوژی های مایکروسافتی مثل مجموعه نرم افزارهای Office، یا IE، یا CLR در دات نت، و غیره مبتنی بر COM هستند. توضیحات مفصل درباره COM و کاربردهای آن را می تونید از لینک زیر مطالعه کنید:

http://en.wikipedia.org/wiki/Component_Object_Model

برای اینکه بتونید از یک کامپوننت COM در برنامه خودتان استفاده کنید، باید ابتدا اون کامپوننت در سیستم مربوطه رجیستر شده باشه. هر سیستم ویندوزی لیستی از کامپوننت های COM رجیستر شده در آن سیستم را نگهداری میکنه. اون وقت سایر برنامه ها می تونند با استفاده از API های مخصوص COM که مایکروسافت تعریف کرده، این کامپوننت ها را لود کنند، و ازشون استفاده کنند. همانطور که قبلا گفتم، COM شی گرا هست، و DLL های حاوی کامپوننت های COM مثل DLL های معمولی ویندوز نیستند که صرفا یک لیست از توابع Export شده داشته باشند که شما بتونید اونها رو فراخوانی کنید، بلکه باید ابتدا از کلاس مربوطه یک شی بسازید، سپس متدهای اون شی را فراخوانی کنید. COM یک مبحث پیچیده و طولانی در برنامه نویسی ویندوز هست که درباره اش کلی کتاب نوشته شده. می تونید با یک جستجوی اینترنتی با اون بیشتر آشنا بشید.

Ananas
جمعه 26 اسفند 1390, 13:29 عصر
سلام.
خیلی ممنون آقای کشاورز. منظورتون اینه که اشیای COM که یک GUID 128 بیتی دارن تو ریجیستری ثبت میشه؟. این GUID چه کاربرد دیگه ای داره فقط برای رجیستر کردن استفاده میشه؟

vcldeveloper
جمعه 26 اسفند 1390, 13:38 عصر
منظورتون اینه که اشیای COM که یک GUID 128 بیتی دارن تو ریجیستری ثبت میشه؟. این GUID چه کاربرد دیگه ای داره فقط برای رجیستر کردن استفاده میشه؟
هر شی COM یک اینترفیس داره که اون اینترفیس باید یک شناسه منحصر به فرد داشته باشه که بشه از طریق اون شناسه اون رو در یک سیستم یا در یک شبکه شناسایی کرد. این شناسه منحصر به فرد همون GUID هست. وقتی یک شی COM را رجیستر می کنید، GUID اون در رجستری سیستم ثبت میشه، و از روی آن میشه به مشخصات لازم برای لود کردن اون شی خاص دسترسی پیدا کرد. البته نیازی نیست که برنامه نویس خودش مستقیما برای لود کردن اشیاء COM از رجیستری ویندوز استفاده کنه، بلکه توابع API ایی مثل CreateComObject برای این کار فراهم شدند که با فراخوانی آن، شی مربوطه توسط سیستم شناسایی و لود میشه.

Ananas
جمعه 26 اسفند 1390, 14:08 عصر
DLL هایی که دایرکت ایکس دارن هم با pascal هم با C++‎‎ و احتمالا با vb و C#‎‎ هم استفاده میشن. اگه این کلاس ها رو به شکل class تعریف میکردن نمیشد این قابلیت رو داشته باشه که با هر زبانی بشه ازش استفاده کرد؟ حتما باید با Inteface و COM این کلاس ها رو تعریف می کردن؟ یعنی DLL ای که با مثلا pascal ساخته میشه بدون استفاده از COM و GUID راحت با C++‎‎ یا C#‎‎ خونده نمیشه؟
و اینکه حتما همه ی Inteface های DirectX موقع نصب ویندوز رجیستر شدن و موقع نصب DirectX فقط dll ها کپی میشن؟ یا اصلا لزومی نداره همشون رجیستر شده باشن تا کار کنن؟ چون dll ها رو دستی هم کپی میکنم کار میکنه.

barnamenevisforme
جمعه 26 اسفند 1390, 15:24 عصر
سلام
جناب آقای کشاورز،استاد ارجمند
من پس از بررسی ها و تحقیق های به نظر کافی(البته به نظر خودم) تصمیم گرفتم که جوابم رو از این سایت بگیرم.
پاسخ های نوشتاری شما بسیار ارزشمند هستندولیکن اگر یه مثال کاربردی از خودتون به جا می گذاشتید،برای بنده بسیار قابل درکتر بود.(البته اگه باعث زحمتتون نمیشه)
آخه هر کسی از طرق یه روش بخصوص مسائل رو درک میکنه.(زبان برنامه نویسی من vb.net)
ممنون.

vcldeveloper
جمعه 26 اسفند 1390, 17:17 عصر
DLL هایی که دایرکت ایکس دارن هم با pascal هم با C++‎‎‎‎ و احتمالا با vb و C#‎‎‎‎ هم استفاده میشن. اگه این کلاس ها رو به شکل class تعریف میکردن نمیشد این قابلیت رو داشته باشه که با هر زبانی بشه ازش استفاده کرد؟ نه، زبان های برنامه نویسی مختلف ساختار داده مختلف و معماری حافظه متفاوتی دارند، در نتیجه نمیشه کلاسی که فرضا در دلفی تعریف شده را همینطوری، بدون هیچ واسطه ای، در ++C یا سایر زبان ها استفاده کرد. دلفی کلاس ها و اشیاء را در حافظه یک طور نگه داری میکنه، ++C طور دیگه.


یعنی DLL ای که با مثلا pascal ساخته میشه بدون استفاده از COM و GUID راحت با C++‎‎‎‎ یا C#‎‎‎‎ خونده نمیشه؟
DLL ایی که با یک زبان ساخته میشه، توسط سایر زبان ها قابل استفاده هست، به شرطی که اولا اون DLL فقط تابع Export کنه، و ثانیا Calling Convention استفاده شده بر اون توابع، و نوع داده پارامترهای اون توابع برای سایر زبان ها نیز قابل فهم باشه. به عنوان مثال DLL های سیستم عامل ویندوز عموما با C نوشته شدند، و در سایر زبان ها مثل پاسکال، ++C یا #C توابع آنها قابل فراخوانی هستند.



ولیکن اگر یه مثال کاربردی از خودتون به جا می گذاشتید،برای بنده بسیار قابل درکتر بود.مثال از چه چیزی؟ استفاده از یک شی COM ؟ اگر همین منظورتون هست، این یک مثال ساده که اگر MS Word روی سیستم تان نصب باشه، یک شی از رابط COM آن ایجاد میکنه، و از طریق آن یک فایل Word را باز میکنه، و یک متن (This is a test) به ابتدای فایل اضافه میکنه. از طریق رابط COM برنامه MS Word میتونید تقریبا تمامی قابلیت های برنامه Word را از داخل برنامه خودتان کنترل کنید:

uses
Variants, ComObj, OleServer;

procedure TestMSWord(const FileName: string);
var
_vTrue : oleVariant;
_vFalse : oleVariant;

_FileName : OleVariant;

Paragraph : OleVariant;
WordApp : OleVariant;
WordDoc : OleVariant;
begin
_vTrue := True;
_vFalse := False;
_FileName := FileName;

WordApp := CreateOleObject('Word.Application');
if not VarIsNull(WordApp) then
try
WordDoc := WordApp.Documents.Open(_FileName,_vFalse,_vFalse,_ vFalse,EmptyParam,
EmptyParam,_vFalse,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,_vFalse,_vFalse,
EmptyParam,_vTrue);
if not VarIsNull(WordDoc) then
begin
Paragraph := WordDoc.Paragraphs.Item(1);
Paragraph.Range.InsertBefore(' This is a test ');
WordDoc.SaveAs(_FileName,EmptyParam,EmptyParam,Emp tyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyP aram,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyP aram,EmptyParam);
end;
finally
WordApp.Quit(_vFalse,EmptyParam,EmptyParam);
end;
end;

Ananas
جمعه 26 اسفند 1390, 18:56 عصر
و ثانیا Calling Convention استفاده شده بر اون توابع، و نوع داده پارامترهای اون توابع برای سایر زبان ها نیز قابل فهم باشه.
مثلا stdcall ؟
اگه بخوام یک یونیت که چند وقت یکبار اون رو تغییر می دم و چیزایی به اون اضافه میکنم و با pascal نوشتم رو تو c++Builder داشته باشم بهترین روش چیه؟ از dll استفاده کنم یا lib یا rtl یا هیچ کدوم ، یا اینکه کلا از نو به زبان c++ بنویسم و اینکه کلاس هام رو به شیوه com و Interface در بیارم یا نه؟
خیلی ممنون که راهنمایی می کنید.

vcldeveloper
جمعه 26 اسفند 1390, 22:18 عصر
مثلا stdcall ؟
بله، stdcall در واقع Calling Convention پیش فرض API های ویندوز هست.


اگه بخوام یک یونیت که چند وقت یکبار اون رو تغییر می دم و چیزایی به اون اضافه میکنم و با pascal نوشتم رو تو C++‎Builder داشته باشم بهترین روش چیه؟ از dll استفاده کنم یا lib یا rtl یا هیچ کدوم ، یا اینکه کلا از نو به زبان C++‎ بنویسم و اینکه کلاس هام رو به شیوه com و Interface در بیارم یا نه؟
بستگی داره که اون یونیت چه چیزهایی بخواد ارائه کنه؛ اگر بخواد کلاس بده، باید باز بررسی بشه که آیا ارزش داره که از COM استفاده بشه یا نه؟ COM پیچیدگی های خاص خودش رو داره، و اگر توجیه مناسبی برای استفاده کردن ازش نداشته باشید، بهتره که ازش دوری کنید. البته C++ Builder به طور کلی وضعش فرق میکنه، چون میتونه مستقیما کلاس های دلفی رو استفاده کنه، پس اگر هدف فقط C++ Builder هست، می تونید از همون کلاس های دلفی استفاده کنید، بدون اینکه درگیر چیز پیچیده ای بشید.

Ananas
جمعه 26 اسفند 1390, 23:28 عصر
بستگی داره که اون یونیت چه چیزهایی بخواد ارائه کنه؛ اگر بخواد کلاس بده، باید باز بررسی بشه که آیا ارزش داره که از COM استفاده بشه یا نه؟ COM پیچیدگی های خاص خودش رو داره، و اگر توجیه مناسبی برای استفاده کردن ازش نداشته باشید، بهتره که ازش دوری کنید.
کلاس هایی هست که اشیای دایرکت تری دی و اطلاعات لازم برای صحنه سه بعدی رو در خودش ذخیره میکنه و یک صحنه سه بعدی رو از فایل میخونه و ذخیره میکنه که قبلا بیشتر قسمت هاشو به شکل record نوشته بودم که با تغییر اونها به کلاس کنترل حافظه بهتری پیدا کردم. در اینجا کار خاصی با COM ندارم که با کلاس نتونم اجرا کنم فقط می خوام اونها رو راحت تر به c++ منتقل کنم.

البته C++‎‎ Builder به طور کلی وضعش فرق میکنه، چون میتونه مستقیما کلاس های دلفی رو استفاده کنه، پس اگر هدف فقط C++‎‎ Builder هست، می تونید از همون کلاس های دلفی استفاده کنید، بدون اینکه درگیر چیز پیچیده ای بشید.
بله هدف دقیقا C++‎Builder هست. با همون dll دیگه؟ یا bpl یا مستقیما از کد های pascal و فایل .pas چنین امکانی هست؟ اگه نه پس چطوری؟
یه سوال دیگه برام مونده اینکه فرق bpl با dll اینه که با bpl لازم نیست کاربر bpl رو داشته باشه و اطلاعات لازم موقع کامپایل داخل exe ذخیره میشه. این رو درست متوجه شدم؟ همینجوره؟ و اگه یک dll داشته باشیم که source ش رو نداشته یاشیم میشه طوری کامپایل کنیم که فقط اطلاعات و توابعی که ازشون استفاده کردیم داخل exe ذخیره بشن و از شر dll خلاص شیم.
ببخشید سوالا زیاد شد.

BORHAN TEC
شنبه 27 اسفند 1390, 08:34 صبح
بله هدف دقیقا C++‎‎‎Builder هست. با همون dll دیگه؟ یا bpl یا مستقیما از کد های pascal و فایل .pas چنین امکانی هست؟ اگه نه پس چطوری؟شما می توانید مستقیماً این ترکیب را با فایلهای pas انجام دهید.

یه سوال دیگه برام مونده اینکه فرق bpl با dll اینه که با bpl لازم نیست کاربر bpl رو داشته باشه و اطلاعات لازم موقع کامپایل داخل exe ذخیره میشه. این رو درست متوجه شدم؟در شرایطی، یکی از تفاوتها میتونه همین باشه ولی تفاوت اصلی اینه که فایلهایی dll استاندارد فقط می توانند توابع و روالها را به اشتراک بگذارند ولی در bpl ها شما می توانید یک رابط از یک کلاس را نیز به اشتراک بگذارید.

و اگه یک dll داشته باشیم که source ش رو نداشته یاشیم میشه طوری کامپایل کنیم که فقط اطلاعات و توابعی که ازشون استفاده کردیم داخل exe ذخیره بشن و از شر dll خلاص شیم.تا اونجایی که من میدونم در دلفی نمیشه این کار رو کرد مگر اینکه dll مربوطه را به صورت resource در فایل exe قرار بدین و با استفاده از تکنیکهایی از اون استفاده کنید. البته یادمه که قبلاً در این مورد در همین سایت بحثهایی شده بود.

Ananas
شنبه 27 اسفند 1390, 11:36 صبح
شما می توانید مستقیماً این ترکیب را با فایلهای pas انجام دهید.
چطوری از کجا شروع کنم؟ به نظرتون متن اصلی برنامه با c++ باشه بعد منتقل بشه به pascal بهتره یا از pascal منتقل بشه به c++؟ هم از نظر سرعت اجرا هم از نظر برنامه نویسی راحت تر.

BORHAN TEC
شنبه 27 اسفند 1390, 13:52 عصر
در حالت کلی در C++‎‎ Builder مستقیماً می توان از کد های دلفی استفاده کرد. ولی نمی توان مستقیماً از کدهای C++‎‎ Builder در دلفی استفاده کرد.

هم از نظر سرعت اجرا هم از نظر برنامه نویسی راحت تر. با توجه با توضیحی که در بالا به آن اشاره کردم. خودتون باید بتونید به این سوال جواب بدین. از لحاظ سرعت هم طبق تست هایی که انجام داده ام سرعت اجرای برنامه های دلفی با C++‎‎ Builder یکسان است و تقریباً هیچ تفاوتی ندارند.

vcldeveloper
شنبه 27 اسفند 1390, 14:08 عصر
بله هدف دقیقا C++‎‎Builder هست. با همون dll دیگه؟ یا bpl یا مستقیما از کد های pascal و فایل .pas چنین امکانی هست؟ اگه نه پس چطوری؟
C++ Builder یک کامپایلر دلفی به طور داخلی داره، و میتونه کدهای دلفی را متوجه بشه. پس مشکلی از این جهت ندارید. بسیاری از کامپوننت هایی هم که برای دلفی نوشته میشند، به راحتی قابل استفاده در C++ Builder هستند.


یه سوال دیگه برام مونده اینکه فرق bpl با dll اینه که با bpl لازم نیست کاربر bpl رو داشته باشه و اطلاعات لازم موقع کامپایل داخل exe ذخیره میشه.
نه دقیقا؛ با BPL به تنهایی نمی تونید همچین حالتی داشته باشید. اگر برنامه شما به صورت Build with runtime packages کامپایل شده باشه، می تونید در کنار برنامه تون BPL داشته باشید. در این حالت مزیت BPL نسبت به DLL در امکان Export کلاس و Type هست. اگر برنامه به صورت Build with runtime packages کامپایل نشده باشه، باید فایل های PAS یا DCU مربوطه وجود داشته باشند، تا لینکر بتونه کدهای استفاده شده در هر یک از آنها را به فایل EXE نهایی پیوند بزنه، و یک فایل EXE به صورت stand-alone تولید کنه که نیاز به BPL نداشته باشه.


اگه یک dll داشته باشیم که source ش رو نداشته یاشیم میشه طوری کامپایل کنیم که فقط اطلاعات و توابعی که ازشون استفاده کردیم داخل exe ذخیره بشن و از شر dll خلاص شیم.
نه

Ananas
شنبه 27 اسفند 1390, 15:10 عصر
خیلی خیلی ممنون. عالیه.
من یونیت pas رو تو پروژه c++builder اضافه کردم و خودش فایل hpp به همون نام و در همون پوشه برام ساخت. بعد اون فایل hpp رو با include در پروژه c++ استفاده کردم.