PDA

View Full Version : ReadFile از توابع API اشک من رو در آورد



Developer Programmer
دوشنبه 25 آبان 1383, 23:25 عصر
توسط APIهای CreateFile به مودم متصل میشم و با WriteFile دستوری مثل ATI رو میفرستم حال میخوام با ReadFile خروجی مودم رو بخونم.شکل زیر ساختار کلی API است که از MSDN در آوردم



BOOL ReadFile(HANDLE hFile, // handle to file
LPVOID lpBuffer, // data buffer
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // number of bytes read
LPOVERLAPPED lpOverlapped // overlapped buffer
);

و حالا من کدم رو اینطور تعریف میکنم


var
hFile : THandle;
lpFileName : PChar;
lpBuffer : String;
nNumberOfBytesToRead : Cardinal;
lpNumberOfBytesRead : Cardinal;
lpOverlapped : POverlapped;
lp : Pointer;
begin
lpBuffer:='';
nNumberOfBytesToRead:=100;
lpNumberOfBytesRead:=0;
lp:=nil;
lp:=@lpBuffer;
ReadFile(hFile,lp,nNumberOfBytesToRead,lpNumberOfB ytesRead,nil);
ShowMessage('ReadFile error: '+IntToStr(GetLastError));
CloseHandle(hFile);
end;

اما بافر برگشتی همیشه تهی است :mad: چرا؟ :sad2:

مهدی کرامتی
سه شنبه 26 آبان 1383, 01:29 صبح
<span dir=ltr>Abstract:
A component that provides functions to read and write synchron from the RS232 via strings


Solution:
Attached with this article is a full component that handles communication with the RS232.

I want to point out only one interesting aspect. Every communication with the rs232 is asyncron. You never know exactly when bits are arriving...
The ReadString method from TRS232 is like serializing the communication. You can call ReadString and pass the amount of characters that you would like to receive. The function only returns when enough characters did arrive or is running into a timeout. For some cases this is useful !
(During the loop it's doing a Application.ProcessMessages so that events from the main program can be executed !)


Here is the ReadString method out of many other function from the component TRS323: </span>

function TRS232.ReadString&#40;VAR aResStr&#58; string; aCount&#58; word &#41;&#58; boolean;
var
nRead&#58; dword;
Buffer&#58; string;
Actual, Before&#58; TDateTime;
TimeOutMin, TimeOutSec, lCount&#58; word;
begin
Result &#58;= false;
if not Connected then
if not Connect then raise Exception.CreateHelp
&#40;'RS232.ReadString&#58;'+
' Connect not possible !', 101&#41;;
aResStr &#58;= '';
TimeOutMin&#58;=TimeOut div 60;
TimeOutSec&#58;=TimeOut mod 60;
if &#40;not Connected&#41; or &#40;aCount &lt;= 0&#41; then EXIT;
nRead &#58;= 0; lCount &#58;= 0;
Before &#58;= Time;
while lCount begin
Application.ProcessMessages;
SetLength&#40;Buffer,1&#41;;
if ReadFile&#40; FComPortHandle, PChar&#40;Buffer&#41;^, 1, nRead, nil &#41;
then
begin
if nRead > 0 then
begin
aResStr &#58;= aResStr + Buffer;
inc&#40;lCount&#41;;
end;
Actual &#58;= Time;
if Actual-Before>EncodeTime&#40;0, TimeOutMin, TimeOutSec, 0&#41;
then raise Exception.CreateHelp&#40;'RS232.ReadString&#58;
TimeOut !', 103&#41;;
end
else begin
raise Exception.CreateHelp&#40;'RS232.ReadString&#58; Read not
possible !', 104&#41;;
end;
end; // while
Result&#58;=true;
end;

Developer Programmer
سه شنبه 26 آبان 1383, 17:52 عصر
:confy2: آقا هزار گل سرخ تقدیم به سرورم حاج کرامتی :flower:

Developer Programmer
چهارشنبه 27 آبان 1383, 09:46 صبح
جناب کرامتی ضمن تشکر دوباره :flower:
طبق توضیحات شما من کد رو به این صورت تغییر دادم


var
Dummy,lpBuffer&#58;String
begin
Repeat
Application.ProcessMessages;
SetLength&#40;lpbuffer,1&#41;;
ReadFile&#40;hFile,Pchar&#40;lpBuffer&#41;^,nNumberOfBytesToRe ad,lpNumberOfBytesRead,nil&#41;;
Dummy&#58;=Dummy+lpBuffer;
sleep&#40;300&#41;;
Until lpNumberOfBytesRead=0;
end;

گاهی بافر خالیه(یعنی lpNumberOfBytesRead=0) و گاهی عبارت
Pchar&#40;lpbuffer&#41;^ باعث میشه که خطای دسترسی غیرمجاز به حافظه رو بده :sad2:
وقتی هم از کامپوننت شما استفاده میکنم


var
PortDrive&#58;TCommPortDriver;
Rs232&#58;Trs232;
Buffer&#58;String;
begin
Rs232.ComPort&#58;=pnCOM3;
Rs232.Connect;
if Rs232.Connected then
begin
Application.ProcessMessages;
RS232.SendString&#40;'ATI'+#13+#10&#41;; &#123;Error&#58; " RS232.SendString&#58; Send not possible !"&#125;
RS232.ReadString&#40;Buffer,10&#41;;
end;
ShowMessage&#40;Buffer&#41;;
end;

خطای RS232.SendString: Send not possible رو میده :sorry: