PDA

View Full Version : فراخوانی داینامیک یک تابع در DLL



Delphi Skyline
یک شنبه 24 شهریور 1387, 00:39 صبح
تابع زیر نام DLL و نام تابع مورد نظر را گرفته و اجرا می کند ولی تابعی که قصد فراخوانی داریم یک پارامتر از نوع عدد صحیح دارد . هنگام کامپایل کد زیر کامپایلر خطای داخلی را گوش زد می کند . تنها در صورتی که یک عدد به ورودی تابع داده شود کامپایل می شود وگرنه اگر متغیر باشد خطا می دهد . می خواستم ببینم مشکل از کجاست . با تشکر .

function LoadAndRunDLLProcedure(
sDLL,
sFunc : string )
: boolean;
type
// define the type of "function"
// we're calling
TFunc_Start = procedure(i : integer);
var
Func_Start : TFunc_Start;
ss : integer;
hDll : THandle;
FuncPtr : TFarProc;
sMsg : string;
begin
Result := False;
hDll := LoadLibrary(
PChar( sDLL ) );
if(hDll > 32)then
begin
FuncPtr :=
GetProcAddress(
hDll, PChar( sFunc ) );
@Func_Start := FuncPtr;
if(nil <> @Func_Start)then
begin
//ss := -;
Func_Start(ss);
Result := True;
end else
begin
sMsg := 'DLL entry point ' +
sFunc + ' not found';
MessageBox(
0, PChar( sMsg ), 'Error',
MB_OK );
end;
FreeLibrary( hDll );
end else
begin
sMsg := 'File ' + sDLL +
' not found';
MessageBox(
0, PChar( sMsg ), 'Error',
MB_OK );
end;
end;

Delphi Skyline
یک شنبه 24 شهریور 1387, 00:46 صبح
مشکل حل شد . باید انتقال پارامتر توسط اشاره گر ها صورت گیرد .

vcldeveloper
یک شنبه 24 شهریور 1387, 15:41 عصر
باید انتقال پارامتر توسط اشاره گر ها صورت گیرد .
نه، مشکل از کد نبود. مشکل از جای دیگه هست. شاید لازم هست یک بار IDE دلفی را ببندید و مجددا باز کنید.
کد بالا به شکل زیر بدون مشکل استفاده شد:


procedure TForm1.Button1Click(Sender: TObject);
var
R :Boolean;
begin
R := LoadAndRunDLLProcedure('Project2.dll','Test');
ShowMessage(BoolToStr(R,True));
end;

کد DLL:


procedure Test(i : integer);
var
j : integer;
begin
for j := 0 to i do
begin
Dec(i);
end;
Sleep(3000);
end;

یک نکته: عادت کنید که برای توابع Export شده از DLL خودتون از stdcall به عنوان Calling Convention استفاده کنید. وقتی از DLL در برنامه های دلفی استفاده می کنید، مشکلی پیش نمیاد، ولی اگر قرار باشه در برنامه های نوشته شده با زبان های دیگه استفاده بشه، به مشکل اساسی بر می خورید!

یک نکته دیگه: String را بصورت const به عنوان پارامتر برای توابع تعریف کنید، غیر از اینکه لازم باشه اون string را در داخل تابع ویرایش کنید. این کار کارایی کدتان را بالا میبره.