PDA

View Full Version : مشکل کجاست ؟



arash_a
یک شنبه 20 آذر 1384, 02:32 صبح
سلام
من این DLL رو تو دلفی بصورت دینامیک می خوام بنویسم ولی اصلا مسیرش رو تو اشاره گر نمی زاره کجای کار ایراد داره ؟
سورس DLL :

library arash;

uses
SysUtils,
Classes,
dialogs,
winprocs;

Function ara:string ;
begin
ara := 'Hello World !!' ;
end;
exports
ara;

begin
end.


و سورس برنامه :

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
DLLhandle : Thandle ;
Function ara:string ; external 'arash.dll' ;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Type
Tara = Function : string ;
Var
s : Tara ;
st : string ;
begin
@s := GetProcAddress (DLLhandle,'ara');
if @s<>nil then
st := s
else
showmessage (' No address is linked correct !!');
edit1.Text := st ;
end;

end.

ممنون میشم مشکا کار رو بگین !!

MiRHaDi
یک شنبه 20 آذر 1384, 19:18 عصر
سلام
عزیزم DLL که توی Ram باز نیست که بتونی اشاره گر به تابعش بدی !
این کارو تو برنامه خودت میتونی انجام بدی DLL جدا اجرا میشه و ربطی نداره و منطقا اشتیاهه
بای

vcldeveloper
دوشنبه 21 آذر 1384, 02:49 صبح
سه تا مشکل وجود داره:
1- قبل از استفاده از GetProcAddress، باید DLLHandle یک هندل معتبر Dll را داشته باشه؛ یعنی باید اول با استفاده از LoadLibrary فایل Dll مربوطه را در فضای آدرس Process مورد نظر لود کنید و هندل اون رو به DllHandle اختصاص بدید تا بتونید با استفاده از GetProcAddress به تابع مورد نظر دسترسی داشته باشید.

2- در Dll ها نباید دادهایی از نوع Dynamic Array یا String بین DLL و برنامه استفاده کننده از اون ردوبدل بشه، برای این منظور باید بجای string از ShortString یا PChar استفاده کنید. اگر مطمئن هستید که برنامه استفاده کننده از Dll شما همیشه یک برنامه نوشته شده با دلفی هست، می تونید از یونیت ShareMem و فایل BorlandMM.Dll استفاده کنید؛ وقتی Dll جدیدی در دلفی ایجاد می کنید (با استفاده از DLL Wizard)، دلفی بصورت خودکار یک Comment در کد شما ایجاد میکنه که در اون نحوه استفاده از ShareMem و BorlandMM.dll توضیح داده شده.

3- در صورتی که قصد دارید از این DLL در برنامه هایی که با زبانهایی غیر دلفی نوشته شده اند استفاده کنید، باید از StdCall بعنوان Calling Convention توابع DLL خودتون استفاده کنید؛ یعنی عبارت StdCall را در انتهای تعریف تابع بنویسید.

arash_a
دوشنبه 21 آذر 1384, 07:33 صبح
سه تا مشکل وجود داره:
1- قبل از استفاده از GetProcAddress، باید DLLHandle یک هندل معتبر Dll را داشته باشه؛ یعنی باید اول با استفاده از LoadLibrary فایل Dll مربوطه را در فضای آدرس Process مورد نظر لود کنید و هندل اون رو به DllHandle اختصاص بدید تا بتونید با استفاده از GetProcAddress به تابع مورد نظر دسترسی داشته باشید.

2- در Dll ها نباید دادهایی از نوع Dynamic Array یا String بین DLL و برنامه استفاده کننده از اون ردوبدل بشه، برای این منظور باید بجای string از ShortString یا PChar استفاده کنید. اگر مطمئن هستید که برنامه استفاده کننده از Dll شما همیشه یک برنامه نوشته شده با دلفی هست، می تونید از یونیت ShareMem و فایل BorlandMM.Dll استفاده کنید؛ وقتی Dll جدیدی در دلفی ایجاد می کنید (با استفاده از DLL Wizard)، دلفی بصورت خودکار یک Comment در کد شما ایجاد میکنه که در اون نحوه استفاده از ShareMem و BorlandMM.dll توضیح داده شده.

3- در صورتی که قصد دارید از این DLL در برنامه هایی که با زبانهایی غیر دلفی نوشته شده اند استفاده کنید، باید از StdCall بعنوان Calling Convention توابع DLL خودتون استفاده کنید؛ یعنی عبارت StdCall را در انتهای تعریف تابع بنویسید.

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

vcldeveloper
سه شنبه 22 آذر 1384, 02:02 صبح
library arash;

uses
SysUtils,
Classes,
dialogs,
winprocs;

Function ara:shortstring ;stdcall;
begin
ara := 'Hello World !!' ;
end;
exports
ara;

begin
end.
--------------------------------

procedure TForm1.Button1Click(Sender: TObject);
Type
Tara = Function : ShortString ;
Var
s : Tara ;
st : string ;
begin
DllHandle := LoadLibrary('arash.dll');
if DllHandle = INVALID_HANDLE_VALUE then
Exit;
try
@s := GetProcAddress (DLLhandle,'ara');
if @s<>nil then
st := s
else
showmessage (' No address is linked correct !!');
edit1.Text := st ;
finally
FreeLibrary(DllHandle);
end;
end;

arash_a
سه شنبه 22 آذر 1384, 07:54 صبح
ممنون آقای کشاورزی ولی من نوشته های شمارو که اجرا کردم خطا میده و می گه :
که یا برنامه رو Pause و یا Stop بکن و خطا هم مربوط به خطای CPU هستش !!!!
:گیج:

vcldeveloper
پنج شنبه 24 آذر 1384, 01:47 صبح
در کد بالای خط چین مربوط به DLL هست. کد زیر خط چین فقط بخشی از کد برنامه ایی هست که DLL را فراخوانی می کنه. من در بخش type از متد TForm1.Button1Click عبارت Tara = Function : string را باید بصورت Tara = Function : ShortString تغییر می دادم که فراموش کردم، همچنین Handle فایل DLL را هم آزاد نکرده بودم. کد را اصلاح کردم.
در ضمن در کد شما، وقتی DLL بصورت دینامیک فراخوانی میشه، دیگه نیازی به Function ara:string ; external 'arash.dll' نیست.

موفق باشید

arash_a
پنج شنبه 24 آذر 1384, 06:18 صبح
ممنون از راهنمایی هاتون.
آقای کشاورزی تونستم با راهنمایی هاتون به کمک ShortString ارتباط متغیر متنی بکنم .
بعد به کمک SharMem هم اومدم String فرستادم به این ترتیب که :
در بخش USES هم DLL و هم برنامه SharMem رو اضافه کردم و درست هم کار کرد ولی موقع بستن برنامه
Dont Send میده و Run Time Error میده !!!!
مشکل از کجاست ؟ :متعجب:

vcldeveloper
جمعه 25 آذر 1384, 02:06 صبح
ولی موقع بستن برنامهDont Send میده و Run Time Error میده !!!!
مشکل از کجاست ؟
برنامه را خط به خط اجرا کنید (یا از Break Point) استفاده کنید تا متوجه بشید کدوم قسمت از کد موجب ایحاد Runtime error میشه.

arash_a
شنبه 26 آذر 1384, 01:11 صبح
برنامه را خط به خط اجرا کنید (یا از Break Point) استفاده کنید تا متوجه بشید کدوم قسمت از کد موجب ایحاد Runtime error میشه.

والا آقای کشاورزی خط بخ خط اجرا کردم و تا آخرش رفتم هیچ خطایی نداد !!!!
ولی موقعی که می خواستم که برنامه رو ببندم دوباره خطای CPU داد !!!
من تو بخش USES از Sharemem تو برنامه و DLL استفاده کردم فکر کنم از همینه !!
شاید الگوی استفاده از ShareMem واسه String متفاوته ؟!؟! :افسرده:

میشه شما خودتون یه برنامه برای نمونه بنویسید و تو این برنامه با زدن دکمه ای برنامه رفته
متنی را از درون یک DLL بصورت String دعوت کند و توی Edit بندازد .
و بعد متن برنامه ی DLL و Form رو اینجا بزارین ؟ :بوس:
خیلی ممنونتون میشم. :تشویق:

vcldeveloper
شنبه 26 آذر 1384, 01:43 صبح
من تو بخش USES از Sharemem تو برنامه و DLL استفاده کردم فکر کنم از همینه !!
شاید الگوی استفاده از ShareMem واسه String متفاوته ؟!؟!
ShareMem باید در هر دو برنامه (DLL و برنامه استفاده کننده از آن) اولین یونیت در بخش Uses باشه.

arash_a
شنبه 26 آذر 1384, 08:04 صبح
ShareMem باید در هر دو برنامه (DLL و برنامه استفاده کننده از آن) اولین یونیت در بخش Uses باشه.

بله آقای کشاورزی در هر دو استفاده کرده ام !!!! :گیج:
:گریه:

vcldeveloper
چهارشنبه 30 آذر 1384, 02:07 صبح
ظاهرا مشکلی که در هنگام بسته شدن برنامه بوجود میاد از یونیت ShareMem هست. ممکنه در سایت های مربوط به Borland برای اون راه حل هایی ارائه شده باشه. من برای استفاده از نوع داده string از یونیت FastMemShare که سریعتر و کاراتر از ShareMem دلفی هست استفاده کردم و مشکلی نداشت. شما می تونید به راحتی FastShareMem را از اینترنت دانلود کنید.
به عنوان ضمیمه هم یک نمونه از بارگزاری دینامیک DLL و استفاده از نوع داده ShortString را براتون گذاشتم.

موفق باشید.

arash_a
پنج شنبه 01 دی 1384, 01:36 صبح
آقای کشاورزی خیلی ممنون هستم . :تشویق:

:تشویق: