ورود

View Full Version : سوال: بهترین روش برای خواندن دی ال ال و استفاده از آنها



nsco_nsco
چهارشنبه 15 دی 1389, 16:05 عصر
سلام دوستان
من چند مشکل با دی ال ال دارم یکی که می خواستم بدونم روش ایستا بهتر است یا پویا ؟

سوال بعدیم اینه من می خوام یک برنامه به صورت دی ال ال ایجاد کنم و مثلا بعد از چند جمع و تفریق عدد حاصل را در یک متغییر بریزم و سپس در یک برنامه اگزه اون متغییر را بخونم و در یک لیبل بریزم تا بشود نمایش داد .

ممنون می شم کمکم کنید از همتون متشکرم .:خجالت::تشویق:

Nima NT
چهارشنبه 15 دی 1389, 21:36 عصر
اینکه پویا استفاده کنید یا ایستا بستگی به خودتون داره و کاربردی که دارید.
در مورد سوال دوم هم شما در DLL خودتون یک تابع مینویسید که در ورودی اعداد مربوطه رو دریافت و جمع کرده و حاصل رو به عنوان خروجی برگشت بده تنها کاری باید آخر انجام بدید این هست که نام تابع رو در DLL به عنوان Exports قرار بدید.
در سایت کمی جستجو کنید مثالهای فراوانی پیدا میکنید.

nsco_nsco
چهارشنبه 15 دی 1389, 23:06 عصر
سلام
ممنون از جواب سریعتون خیلی گشتم چیز خوبی پیدا نکردم ممنون می شم یکی مثال بزنید البته هم برای دی ال ال و هم برای اگزه با تشکر:تشویق:

Nima NT
پنج شنبه 16 دی 1389, 00:15 صبح
http://delphi.about.com/od/windowsshellapi/a/dll_basics.htm

nsco_nsco
پنج شنبه 16 دی 1389, 00:46 صبح
سلام
این رو قبلا دیدم فقط میاد و یکی فایل دی ال ال رو پکش رو تو اگزه میاره اما من می خوام یکی متغییر اینتیجر به نام علی رو در دی ال ال بنویسم و مقداری بهش بدم و تو اگزه بیارمش و مثلا در لیبل یک نمایش بدم ممنون می شم که راهنمایییم کنید با تشکر :تشویق: لطفا حتما مثال بزنید ممنون :لبخندساده::چشمک:

nsco_nsco
پنج شنبه 16 دی 1389, 15:48 عصر
سلام
لطفا بابت این موضوع من را کمک کنید و حتما یک مثال بزنید ممنون:خجالت:

Nima NT
پنج شنبه 16 دی 1389, 15:59 عصر
مشکل شما در نوشتن DLL نیست مشکل به نظر میاد در کد نویسی هستش ، درست متوجه شدم ؟
چون فرقی نمیکنه که اونجا یک Procedure بنویسید یا یک Function.

vcldeveloper
پنج شنبه 16 دی 1389, 16:55 عصر
من می خوام یکی متغییر اینتیجر به نام علی رو در دی ال ال بنویسم و مقداری بهش بدم و تو اگزه بیارمش و مثلا در لیبل یک نمایش بدم
یک DLL استاندارد ویندوز فقط تابع export میکنه، پس از داخل یک برنامه نمی تونید مستقیما به یک متغیر تعریف شده در داخل DLL دسترسی داشته باشید. برای اینکه بتونید به اون متغیر دسترسی داشته باشید، باید داخل DLL تابعی بنویسید که مقدار اون متغیر رو برگشت بده.

البته نگهداری یک سری مقادیر قابل تغییر در داخل متغیرهای Global تعریف شده در داخل DLL کار جالبی نیست، چون هر پروسه ایی که اون DLL رو لود کنه، میتونه اون مقادیر رو تغییر بده، و در کار سایر پروسه هایی که اون DLL رو لود کردند، مشکل ایجاد کنه؛ مثلا دو پروسه یک DLL را لود می کنند، پروسه اول یک محاسبه انجام میده و نتیجه اش در داخل یک متغیر Global در DLL ذخیره میشه. پروسه دوم هم یک محاسبه انجام میده، و نتیجه اش در همان متغیر ذخیره میشه. حالا اگر پروسه اول بخواد نتیجه محاسبه خودش را دریافت کنه، به جای نتیجه محاسبه خودش، با نتیجه محاسبه پروسه دوم مواجه میشه!

nsco_nsco
پنج شنبه 16 دی 1389, 22:43 عصر
سلام
از همه شما متشکرم اما

من می دونم چطور یک متغییر کار می کنه اما نمی دونم چطور اون رو تعریف کنم که در خارج برنامه که همان فایل اگزه است فراخوانی کنم و از آن استفاده نماییم من می خوام مثلا یک متغییر که دارم در دی ال ال جوری طراحیش کنم که بطونم در یک برنامه از آن استفاده کنم و نحوه کد نویسی این فرایند را درست نمی فهمم ممنون می شم یک دستور معرفی کنید که مثلا متغییر s1 را در دی ال ال مثلا مساوی 10 باشه و این رو در دی ال ال خروجی بده و بعد کدی که در فایل اگزه قرار می گیرد را می خواهم به همین سادگی نمی دونم چرا وارد ریز موضوع می شوید
من تنها کد یک متغییر رو می خواهم نحوه نوشتن دستورات دو فایل اگزه و دی ال ال حتما با مثال
از همه شما متشکرم ممنون می شم سریع جواب بدهید با تشکر فراوان :خجالت::قلب::تشویق:

vcldeveloper
جمعه 17 دی 1389, 00:08 صبح
من می دونم چطور یک متغییر کار می کنه اما نمی دونم چطور اون رو تعریف کنم که در خارج برنامه که همان فایل اگزه است فراخوانی کنم و از آن استفاده نماییم من می خوام مثلا یک متغییر که دارم در دی ال ال جوری طراحیش کنم که بطونم در یک برنامه از آن استفاده کنم و نحوه کد نویسی این فرایند را درست نمی فهمم ممنون می شم یک دستور معرفی کنید که مثلا متغییر s1 را در دی ال ال مثلا مساوی 10 باشه و این رو در دی ال ال خروجی بده و بعد کدی که در فایل اگزه قرار می گیرد را می خواهم به همین سادگی نمی دونم چرا وارد ریز موضوع می شوید
جواب ها را با دقت مطالعه نمی کنید...
گفتم DLL استاندارد ویندوز فقط تابع Export میکنه، یعنی یک DLL استاندارد ویندوز به برنامه هایی که لودش می کنند، فقط یک سری تابع ارائه میکنه؛ پس نمی تونید درش متغیر تعریف کنید، و انتظار داشته باشید اون متغیر از طریق برنامه هایی که اون DLL رو لود می کنند، در دسترس باشه. اگر قرار باشه مقدار متغیری در دسترس قرار بگیره، این کار باید غیر مستقیم و از طریق توابع تعریف شده در همان DLL صورت بگیره، مثلا یک تابع برای مقداردهی به اون متغیر تعریف بشه، و یک تابع هم برای گرفتن مقدار از اون.

جواب ها را با دقت مطالعه کنید تا هم کار خودتون زودتر راه بیافته، و هم ما مجبور نشیم جواب را تکرار کنیم.

موفق باشید

nsco_nsco
جمعه 17 دی 1389, 20:05 عصر
سلام

ممنون از جوابتون پس اگر ممکنه یک تابع ر و مثال بزنید که چطور این فرایند در برنامه اجرا می شود ممنون .:خجالت:

vcldeveloper
شنبه 18 دی 1389, 01:52 صبح
اگر ممکنه یک تابع ر و مثال بزنید که چطور این فرایند در برنامه اجرا می شود
روند کارش مثل فراخوانی هر تابع دیگه هست. در هر حال:


library TestLib;

var
/// Internal storage for the DLL.
/// Note that it is not a good practice to share a global variable inside
/// a DLL with multiple processes. This is only for testing purpose.
MyVariable : Integer;

function GetMyVariable: Integer; stdcall;
begin
Result := MyVariable;
end;

procedure SetMyVariable(const Value: Integer); stdcall;
begin
MyVariable := Value;
end;

exports
GetMyVariable,
SetMyVariable;

begin
/// Make sure the global variable is initialized.
MyVariable := 0;
end.


program Test;

{$APPTYPE CONSOLE}

uses
SysUtils;

function GetMyVariable: Integer; stdcall; external 'TestLib.dll' name 'GetMyVariable';
procedure SetMyVariable(const Value: Integer); stdcall; external 'TestLib.dll' name 'SetMyVariable';

begin
try
/// Send a test value to the DLL
SetMyVariable(4);
/// Retrieve the value stored inside the DLL
Writeln(GetMyVariable);
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

همانطور که در پست قبلی هم گفتم، نگهداری یک داده مشترک قابل تغییر به این صورت در یک DLL کار درستی نیست. فقط چون درخواست مثال کردید، اون رو نوشتم که متوجه روند کار بشید.

nsco_nsco
یک شنبه 19 دی 1389, 15:16 عصر
سلام ممنون از جوابتون
من واقعیتش دارم یک تقویم می سازم البته دی ال ال و می خوام به واسطه تابع آن را فراخوانی در برنامه هام بکنم اگر می گوید کار درستی نیست ممنون می شم راهنماییم کنید که چطوری این مهم را انجام دهم با تشکر :خجالت::تشویق:

vcldeveloper
یک شنبه 19 دی 1389, 15:47 عصر
من واقعیتش دارم یک تقویم می سازم البته دی ال ال و می خوام به واسطه تابع آن را فراخوانی در برنامه هام بکنم اگر می گوید کار درستی نیست ممنون می شم راهنماییم کنید که چطوری این مهم را انجام دهم
اینکه شما در DLL تان مقادیری را ذخیره کنید، یا توابع DLL شما مقادیری بگیرند یا برگشت بدند، به خودی خود مشکلی نداره. اصلا اگر DLL این قابلیت رو نداشته باشه که دیگه ارزش نداره. بحث سر این هست نباید اجازه بدید که مقدار یک متغیر عمومی (Global) را برنامه های مختلفی که یک DLL را لود می کنند، تغییر بدند.

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

nsco_nsco
یک شنبه 19 دی 1389, 22:25 عصر
سلام با عرض شرمندگی و تشکر برای جوابهاتون
نگاه کنید فرض کنید که ما یک برنامه نوشتیم که روزها رو به صورت فارسی نمایش می دهدو این عمل را می خواهیم در یک دی ال ال نمایش بدهیم مثلا:
MyDate:=StrToDateTime(day);
case DayOfWeek(MyDate) of
1: Label2.Caption:='یک شنبه';
2: Label2.Caption:='دوشنبه';
3: Label2.Caption:='سه شنبه';
4: Label2.Caption:='چهارشنبه';
5: Label2.Caption:='پنج شنبه';
6: Label2.Caption:='جمعه';
7: Label2.Caption:='شنبه';
end;

حالا ممنون می شم طبق بالا یک تابع معرفی کنید و نمایش این را در یک فایل اگزه نمایش دهید با این کار خیلی به من کمک می کنید . با تشکر فراوان از شما دوستان
:خجالت::لبخندساده::تشویق:

vcldeveloper
دوشنبه 20 دی 1389, 01:16 صبح
library Project2;

uses
SysUtils;

{$R *.res}

var
PersianDayNames : array [1..7] of string =
('دوشنبه','سه شنبه','چهارشنبه','پنج شنبه','جمعه','شنبه', 'یک شنبه');

function GetDayNameLength(DayOfWeek: Byte): Byte; stdcall;
begin
Result := Length(PersianDayNames[DayOfWeek]);
end;

function GetPersianDayName(DayOfWeek: Byte; DayName: PChar): Boolean; stdcall;
var
Str : string;
begin
Result := False;
Str := PersianDayNames[DayOfWeek];
StrPCopy(DayName,Str);
Result := True;
end;

exports
GetDayNameLength,
GetPersianDayName;

begin
end.



unit Unit3;

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 GetDayNameLength(DayOfWeek: Byte): Byte; stdcall;
external 'Project2.dll' name 'GetDayNameLength';
function GetPersianDayName(DayOfWeek: Byte; DayName: PChar): Boolean; stdcall;
external 'Project2.dll' name 'GetPersianDayName';


var
Form1: TForm1;

implementation

{$R *.dfm}

uses DateUtils;

procedure TForm1.Button1Click(Sender: TObject);
var
DayIndex : Integer;
DayName : string;
begin
DayIndex := DayOfTheWeek(Now);
DayName := StringOfChar(#0,GetDayNameLength(DayIndex));
GetPersianDayName(DayIndex,PChar(DayName));
ShowMessage(DayName);
end;

end.

nsco_nsco
دوشنبه 20 دی 1389, 02:09 صبح
سلام ممنون از شما اقای کشاورز بابت جوابهاتون ممنون می شم در مورد برنامه توضیحاتی درج کنید با تشکر فراوان:خجالت::تشویق:

vcldeveloper
دوشنبه 20 دی 1389, 02:41 صبح
دقیقا چی رو توضیح بدم؟

یک dll هست، با دو تابع، یکی نام روز هفته را برگشت میده، اون یکی تعداد کارکترهای هر یک از روزهای هفته را برگشت میده، تا برنامه فراخوان بدونه باید چقدر حافظه برای مقدار برگشتی اختصاص بده. برای نگهداری نام روزهای هفته هم از یک آرایه استاتیک استفاده شده.

برنامه فراخوان هم یک دکمه داره که با کلیک بر روی آن، شماره روز هفته با استفاده از تابع DayOfTheWeek دلفی به دست میاد، سپس تعداد کارکتر مورد نیاز برای نگهداری نام این روز هفته، با فراخوانی تابع GetDayNameLength از dll به دست میاد، و یک رشته خالی با همان طول ایجاد میشه، سپس تابع GetPersianDayName از dll فراخوانی میشه که نام روز هفته را به فارسی برگشت میده. در نهایت هم نام روز هفته با استفاده از ShowMessage نمایش داده میشه.

nsco_nsco
دوشنبه 20 دی 1389, 04:30 صبح
ممنون از شما
ببینید من دو فایل ساختم یکی دی ال ال و یکی اگزه به ترتیب زیر :




library Project1;

uses
SysUtils;

{$R *.res}

var

day:string;

ff : Integer;


function Getf(ff: Integer): Byte; stdcall;
begin
Getf:=10;

end;

exports

Getf;


begin
end.


اگزه:





unit Unit1;

interface

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

type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
Label2: TLabel;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Form1: TForm1;
DayIndex : Integer;
ff : Integer;
ff1 : string;
DLLhandle : THandle;
DayName : string;
function Getf(ff:string):Integer;external 'Project1.dll';

implementation

{$R *.dfm}

uses DateUtils;

procedure TForm1.Button2Click(Sender: TObject);
begin
FreeLibrary (DLLhandle);
Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
DLLhandle:=Loadlibrary('Project1.dll');

Label1.Caption:=IntToStr(DLLhandle);

end;

end.


این دو فایل را نوشتم البته نمی دونم درست است یا غلط و البته مشکل العان که می خوام مقدار تابع دی ال ال را در اگزه نشان دهم یک سری اعداد الکی نمایش می دهد می خواستم کمک کنید برای درست کردن این مورد لطفا حتما توضیع دهید ممنون .:خجالت::قلب::تشویق:

vcldeveloper
دوشنبه 20 دی 1389, 11:56 صبح
شما باید مشخص کنید که دقیقا چی میخواید. من در این تاپیک دو مثال کامل براتون قرار دادم؛ اما مرتبا پیش فرض های خودتان را تغییر می دید. من نمیدونم الان این کدی که نوشتید، قراره چیکار کنه:
- تابع Getf رو در DLL با یک پارامتر از نوع Integer تعریف کردید، بعد همون تابع رو در پروژه فراخوان DLL با یک پارامتر string تعریف کردید!
- در پروژه فراخوان DLL، خواستید تابع رو به صورت استاتیک لود کنید، اما فقط نام DLL رو نوشتید، و نام تابع موجود در DLL را ذکر نکردید.
- در پروژه فراخوان DLL، سعی کردید همون DLL رو به صورت دینامیک لود کنید، اما معلوم نیست چرا این کار رو انجام دادید.

به طور کلی، معلوم نیست شما دقیقا چی میخواید، و مشکل تون با چی هست؟ با لود استاتیک DLL؟ با لود دینامیک DLL؟ با مفهوم DLL؟ با تعریف یک تابع در پاسکال؟ با برگشت دادن نام روز هفته به فارسی؟ یا چیزهای دیگه؟

nsco_nsco
دوشنبه 20 دی 1389, 16:25 عصر
سلام ببخشید
من واقعیتش با ساخت تابع و فراخوانی مشکل دارم و بهتر بگم مشکلم خیلی زیاد هست هر چی هم سعی می کنم چیز خوبی یاد نمی گیرم واقعیتش می خواهم به صورت پویا فراخوانی انجام بدم اما درست نمی دانم و در صورت امکان یک توضیح کامل بدید و لطفا از متغییرهای ساده نام ببرید ممنون از شما:قلب::خجالت:

vcldeveloper
دوشنبه 20 دی 1389, 17:20 عصر
من واقعیتش با ساخت تابع و فراخوانی مشکل دارم و بهتر بگم مشکلم خیلی زیاد هست هر چی هم سعی می کنم چیز خوبی یاد نمی گیرم واقعیتش می خواهم به صورت پویا فراخوانی انجام بدم اما درست نمی دانم و در صورت امکان یک توضیح کامل بدید
مسئله ایی نیست؛ شما مشکل تان را به بخش های کوچک تر تقسیم کنید، و هر بخش از مشکل تان را در یک تاپیک مجزا بپرسید. مثلا اگر در تعریف تابع مشکل دارید، یک تاپیک ایجاد کنید، و در اون توضیح بدید که چه مشکلی در تعریف تابع دارید. اگر در کار با یک نوع داده خاص مشکل دارید، یک تاپیک درباره آن ایجاد کنید. اگر در لود کردن دینامیک یک DLL مشکل دارید، آن را هم در یک تاپیک مجزا بپرسید. اینطوری مشکلاتتان از هم تفکیک میشند، هم خودتان بهتر اونها را می فهمید، و هم کمک کردن به شما ساده تر میشه. الان من یک مثال میزنم، شما هم در تعریف تابع اش مشکل دارید، هم در نحوه لود DLL اش، هم در نوع های داده به کار رفته؛ پس به درستی اون مثال رو متوجه نمیشد.