PDA

View Full Version : کمک در مورد بهینه کردن کد نوشته شده در یک DLL



dark-man
سه شنبه 10 آذر 1388, 19:25 عصر
با سلام و خسته نباشید خدمت همه اساتید .
من DLLی نوشتم که می خوام کار خاصی رو انجام بده که کدش رو در ادامه پیوست می کنم ، با توجه به تجربه بسیار کمی که در نوشتن DLL دارم . ممنون میشم دوستان با توجه به نیازهایی که از این DLL دارم در بهینه کردن کد کمکم کنند . پیشاپیش از لطفتون سپاسگذارم .

کد :


library amDll;
uses
SysUtils,
Classes,
KDTele_TLB,
Messages,
Windows,
Forms,
UnitKDCommon,
UnitKDPhone;
var
amPhone : TKDPhone;
line_State : TLineState;
lineList : array [1..5] of string;
startTime, endTime : string;
// get collection of line
procedure getLine();
var
lNum : Word;
lName : WideString;
i : Integer;
begin
i := 0;
amPhone := TKDPhone.Create(amPhone);
for lNum := 0 to amPhone.NumberOfLines do
begin
i := i + 1;
amPhone.GetLineName(lNum, lName);
if lName <> '' then
begin
lineList[i] := lName;
end;
end;
end;
// list line for developer
procedure _lineList(var lineListing : string);
var
i : Integer;
begin
for i := 1 to 5 do
begin
lineListing := lineList[i];
end;
end;
// get State of Activate Line
procedure lineState(var _lineState : string);
begin
case line_State of
lsActivated : begin
_lineState := 'خط فعال مي باشد';
end;
lsDeactivated : begin
_lineState := 'خط فعال نيست';
end;
lsError : begin
_lineState := 'خطا در فعال سازي خط';
end;
else
end;
end;
// get Line ID and active Selected Line
procedure lineActive(lineID : Integer; var lineActiveErrorTitle : string);
var
lineActiveError : Integer;
begin
amPhone := TKDPhone.Create(amPhone);
lineActiveError := amPhone.LineActive(lineID, True);
if (lineActiveError <> 0) then
begin
lineActiveErrorTitle := amPhone.GetErrorMsg(lineActiveError);
if lineActiveErrorTitle = 'The telephony device is not compatible with the value specified by the MediaMode property' then
begin
lineActiveErrorTitle := 'مودم انتخاب شده براي برقراري تماس سازگار نيست';
end
else if lineActiveErrorTitle = 'Could not setup the line device' then
begin
lineActiveErrorTitle := 'قادر به فعال سازي اين مودم نيست'
end;
end;
end;
//procedure for dial Number
procedure dialNumber(number : string);
begin
amPhone := TKDPhone.Create(amPhone);
amPhone.DialNumber(number, 0);
startTime := FormatDateTime('hh:mm:ss', Time);
end;
// procedure for hangUp Call
procedure hangUpCall();
begin
amPhone := TKDPhone.Create(amPhone);
amPhone.Hangup;
endTime := FormatDateTime('hh:mm:ss', Time);
end;
// procedure for calculate call Time
procedure callProccess(var totalTime : string);
var
shTime, smTime, ssTime, ehTime, emTime, esTime : string;
hh, mm, ss : Integer;
begin
// start Time
shTime := Copy(startTime, 1, 2);
smTime := Copy(startTime, 4, 2);
ssTime := Copy(startTime, 7, 2);
// end Time
ehTime := Copy(endTime, 1, 2);
emTime := Copy(endTime, 4, 2);
esTime := Copy(endTime, 7, 2);
// calculate Time
hh := StrToInt(ehTime) - StrToInt(shTime);
mm := StrToInt(emTime) - StrToInt(smTime);
ss := StrToInt(esTime) - StrToInt(ssTime);
// return and show Time
totalTime := IntToStr(hh) + ':' + IntToStr(mm) + ':' + IntToStr(ss);
end;
// export important procedure
exports
callProccess, hangUpCall, dialNumber, lineActive, lineState, _lineList;
{$R *.res}
begin
end.

نیازها :

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

ممنون میشم در این زمینه کمکم کنید .

dark-man
سه شنبه 10 آذر 1388, 21:26 عصر
کسی نیست کمکم کنه ؟

vcldeveloper
سه شنبه 10 آذر 1388, 23:23 عصر
من کامل کد رو نخوندم، ولی دو چیز در آن مشهود هست:

1- استفاده از پارامترهای string در توابع DLL به این شکل کاملا اشتباه هست. خودِ DLL Wizard دلفی هم این مورد را بصورت کامنت در زمان ایجاد یک پروژه DLL به شما تذکر میده. در این مورد قبلا در همین تالار چندین بار بحث شده.

2- اشیایی مثل amPhone در کد ساخته میشند، ولی جایی در کد آزاد نشدند! به فرض هم اگر جایی در کد آزاد میشدند، در صورتی که چند برنامه همزمان از این DLL استفاده کنند، باز نشت حافظه بوجود میاد.

dark-man
پنج شنبه 12 آذر 1388, 19:38 عصر
من کامل کد رو نخوندم، ولی دو چیز در آن مشهود هست:

1- استفاده از پارامترهای string در توابع DLL به این شکل کاملا اشتباه هست. خودِ DLL Wizard دلفی هم این مورد را بصورت کامنت در زمان ایجاد یک پروژه DLL به شما تذکر میده. در این مورد قبلا در همین تالار چندین بار بحث شده.

2- اشیایی مثل amPhone در کد ساخته میشند، ولی جایی در کد آزاد نشدند! به فرض هم اگر جایی در کد آزاد میشدند، در صورتی که چند برنامه همزمان از این DLL استفاده کنند، باز نشت حافظه بوجود میاد.


جناب کشاورز طبق فرمایش شما و راهنمای دلفی در مورد string و توابع بنده ShareMem رو به DLL و Application اضافه کردم و مشکل اول رو حل کردم اما الان با خطای دیگه ای مواجه می شم و اون هم Access violation at Address 000000 هست در این مورد نمی دونم باید چه کاری انجام بدم . ممنون میشم راهنمائیم کنید .

AliReza Vafakhah
پنج شنبه 12 آذر 1388, 20:36 عصر
کسی نیست کمکم کنه ؟

دوست عزیز من KDTele رو نصب ندارم ولی خوب کدتون رو به صورت زیر تغییر دادم و یکی از Procedure ها رو به Function تبدیل کردم (البته چندتا دیگه رو هم می شد به Function تبدیل کرد).

خلاصه نتونستم به دلیل نصب نبودن KD کد رو تست کنم ولی خوب یه سری تغیراتی دادم به خصوص تعریف متغیر amPhone که سراسری بود و معلوم نبود که کی آزاد میشه !

راستی من در نوشتن DLL از داده String استفاده نمی کنم و به همین دلیل از ShareMem خبر ندارم و در این خصوص دست کاری انجام ندادم

library amDll;
uses
SysUtils,
Classes,
KDTele_TLB,
Messages,
Windows,
Forms,
UnitKDCommon,
UnitKDPhone,
ShareMem;

var
line_State : TLineState;
lineList : array [1..5] of string;
startTime, endTime : string;
// get collection of line
procedure getLine();
var
lNum : Word;
lName : WideString;
i : Integer;
amPhone : TKDPhone;
begin
try
i := 0;
amPhone := TKDPhone.Create(nil);
for lNum := 0 to amPhone.NumberOfLines do
begin
i := i + 1;
amPhone.GetLineName(lNum, lName);
if lName <> '' then
begin
lineList[i] := lName;
end;
end;
finally
FreeAndNil(amPhone);
end;
end;
// list line for developer
procedure _lineList(var lineListing : TString);
var
i : Integer;
begin
for i := 1 to 5 do
lineListing.Add(lineList[i]);
end;
// get State of Activate Line
Function lineState:String;
begin
case line_State of
lsActivated:
Result := 'خط فعال مي باشد';

lsDeactivated:
Result := 'خط فعال نيست';

lsError:
Result := 'خطا در فعال سازي خط';
else
Result:='';
end;
end;
// get Line ID and active Selected Line
procedure lineActive(lineID : Integer; var lineActiveErrorTitle : string);
var
lineActiveError : Integer;
amPhone : TKDPhone;
begin
try
amPhone := TKDPhone.Create(amPhone);
lineActiveError := amPhone.LineActive(lineID, True);
if (lineActiveError <> 0) then
begin
lineActiveErrorTitle := amPhone.GetErrorMsg(lineActiveError);
if lineActiveErrorTitle = 'The telephony device is not compatible with the value specified by the MediaMode property' then
lineActiveErrorTitle := 'مودم انتخاب شده براي برقراري تماس سازگار نيست'
else if lineActiveErrorTitle = 'Could not setup the line device' then
lineActiveErrorTitle := 'قادر به فعال سازي اين مودم نيست'
end;
finally
FreeAndNil(amPhone);
end;
end;
//procedure for dial Number
procedure dialNumber(const Number : string);
var
amPhone : TKDPhone;
begin
try
amPhone := TKDPhone.Create(amPhone);
amPhone.DialNumber(number, 0);
startTime := FormatDateTime('hh:mm:ss', Time);
finally
FreeAndNil(amPhone);
end;
end;
// procedure for hangUp Call
procedure hangUpCall();
var
amPhone : TKDPhone;
begin
try
amPhone := TKDPhone.Create(amPhone);
amPhone.Hangup;
endTime := FormatDateTime('hh:mm:ss', Time);
finally
FreeAndNil(amPhone);
end;
end;
// procedure for calculate call Time
procedure callProccess(var totalTime : string);
var
shTime, smTime, ssTime, ehTime, emTime, esTime : string;
hh, mm, ss : Integer;
begin
// start Time
shTime := Copy(startTime, 1, 2);
smTime := Copy(startTime, 4, 2);
ssTime := Copy(startTime, 7, 2);
// end Time
ehTime := Copy(endTime, 1, 2);
emTime := Copy(endTime, 4, 2);
esTime := Copy(endTime, 7, 2);
// calculate Time
hh := StrToInt(ehTime) - StrToInt(shTime);
mm := StrToInt(emTime) - StrToInt(smTime);
ss := StrToInt(esTime) - StrToInt(ssTime);
// return and show Time
totalTime := IntToStr(hh) + ':' + IntToStr(mm) + ':' + IntToStr(ss);
end;
// export important procedure
exports
callProccess, hangUpCall, dialNumber, lineActive, lineState, _lineList;
{$R *.res}
begin
end.

dark-man
پنج شنبه 12 آذر 1388, 20:48 عصر
دوست عزیز من KDTele رو نصب ندارم ولی خوب کدتون رو به صورت زیر تغییر دادم و یکی از Procedure ها رو به Function تبدیل کردم (البته چندتا دیگه رو هم می شد به Function تبدیل کرد).

خلاصه نتونستم به دلیل نصب نبودن KD کد رو تست کنم ولی خوب یه سری تغیراتی دادم به خصوص تعریف متغیر amPhone که سراسری بود و معلوم نبود که کی آزاد میشه !

راستی من در نوشتن DLL از داده String استفاده نمی کنم و به همین دلیل از ShareMem خبر ندارم و در این خصوص دست کاری انجام ندادم

library amDll;
uses
SysUtils,
Classes,
KDTele_TLB,
Messages,
Windows,
Forms,
UnitKDCommon,
UnitKDPhone,
ShareMem;

var
line_State : TLineState;
lineList : array [1..5] of string;
startTime, endTime : string;
// get collection of line
procedure getLine();
var
lNum : Word;
lName : WideString;
i : Integer;
amPhone : TKDPhone;
begin
try
i := 0;
amPhone := TKDPhone.Create(nil);
for lNum := 0 to amPhone.NumberOfLines do
begin
i := i + 1;
amPhone.GetLineName(lNum, lName);
if lName <> '' then
begin
lineList[i] := lName;
end;
end;
finally
FreeAndNil(amPhone);
end;
end;
// list line for developer
procedure _lineList(var lineListing : TString);
var
i : Integer;
begin
for i := 1 to 5 do
lineListing.Add(lineList[i]);
end;
// get State of Activate Line
Function lineState:String;
begin
case line_State of
lsActivated:
Result := 'خط فعال مي باشد';

lsDeactivated:
Result := 'خط فعال نيست';

lsError:
Result := 'خطا در فعال سازي خط';
else
Result:='';
end;
end;
// get Line ID and active Selected Line
procedure lineActive(lineID : Integer; var lineActiveErrorTitle : string);
var
lineActiveError : Integer;
amPhone : TKDPhone;
begin
try
amPhone := TKDPhone.Create(amPhone);
lineActiveError := amPhone.LineActive(lineID, True);
if (lineActiveError <> 0) then
begin
lineActiveErrorTitle := amPhone.GetErrorMsg(lineActiveError);
if lineActiveErrorTitle = 'The telephony device is not compatible with the value specified by the MediaMode property' then
lineActiveErrorTitle := 'مودم انتخاب شده براي برقراري تماس سازگار نيست'
else if lineActiveErrorTitle = 'Could not setup the line device' then
lineActiveErrorTitle := 'قادر به فعال سازي اين مودم نيست'
end;
finally
FreeAndNil(amPhone);
end;
end;
//procedure for dial Number
procedure dialNumber(const Number : string);
var
amPhone : TKDPhone;
begin
try
amPhone := TKDPhone.Create(amPhone);
amPhone.DialNumber(number, 0);
startTime := FormatDateTime('hh:mm:ss', Time);
finally
FreeAndNil(amPhone);
end;
end;
// procedure for hangUp Call
procedure hangUpCall();
var
amPhone : TKDPhone;
begin
try
amPhone := TKDPhone.Create(amPhone);
amPhone.Hangup;
endTime := FormatDateTime('hh:mm:ss', Time);
finally
FreeAndNil(amPhone);
end;
end;
// procedure for calculate call Time
procedure callProccess(var totalTime : string);
var
shTime, smTime, ssTime, ehTime, emTime, esTime : string;
hh, mm, ss : Integer;
begin
// start Time
shTime := Copy(startTime, 1, 2);
smTime := Copy(startTime, 4, 2);
ssTime := Copy(startTime, 7, 2);
// end Time
ehTime := Copy(endTime, 1, 2);
emTime := Copy(endTime, 4, 2);
esTime := Copy(endTime, 7, 2);
// calculate Time
hh := StrToInt(ehTime) - StrToInt(shTime);
mm := StrToInt(emTime) - StrToInt(smTime);
ss := StrToInt(esTime) - StrToInt(ssTime);
// return and show Time
totalTime := IntToStr(hh) + ':' + IntToStr(mm) + ':' + IntToStr(ss);
end;
// export important procedure
exports
callProccess, hangUpCall, dialNumber, lineActive, lineState, _lineList;
{$R *.res}
begin
end.


بابت لطفتون ممنون . امیدوارم مشکلم رو حل کنه . در مورد ShareMem اینو می دونم که برای استفاده از String در DLL باید از اون استفاده کرد .

alinikaein
پنج شنبه 12 آذر 1388, 21:40 عصر
براي ShareMem علاوه بر استفاده به عنوان اولين Unit فايل Dll، بايد به عنوان اولين Unit برنامه (نه فرم) هم استفاده بشه.

يا علي... موفق باشيد...