View Full Version : ReadFile از توابع API اشک من رو در آورد
  
Developer Programmer
سه شنبه 26 آبان 1383, 00: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, 02: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(VAR aResStr: string; aCount: word ): boolean;
var
  nRead: dword;
  Buffer: string;
  Actual, Before: TDateTime;
  TimeOutMin, TimeOutSec, lCount: word;
begin
  Result := false;
  if not Connected then
    if not Connect then raise Exception.CreateHelp
                             ('RS232.ReadString:'+
                              ' Connect not possible !', 101);
  aResStr := '';
  TimeOutMin:=TimeOut div 60;
  TimeOutSec:=TimeOut mod 60;
  if (not Connected) or (aCount <= 0) then EXIT;
  nRead := 0; lCount := 0;
  Before := Time;
  while lCount   begin
    Application.ProcessMessages;
    SetLength(Buffer,1);
    if ReadFile( FComPortHandle, PChar(Buffer)^, 1, nRead, nil ) 
    then
    begin
      if nRead > 0 then
      begin
        aResStr := aResStr + Buffer;
        inc(lCount);
      end;
      Actual := Time;
      if Actual-Before>EncodeTime(0, TimeOutMin, TimeOutSec, 0)
      then raise Exception.CreateHelp('RS232.ReadString: 
                                      TimeOut !', 103);
    end
    else begin
      raise Exception.CreateHelp('RS232.ReadString: Read not 
                                  possible !', 104);
    end;
  end; // while
  Result:=true;
end;
Developer Programmer
سه شنبه 26 آبان 1383, 18:52 عصر
:confy2: آقا هزار گل سرخ تقدیم به سرورم حاج کرامتی :flower:
Developer Programmer
چهارشنبه 27 آبان 1383, 10:46 صبح
جناب کرامتی ضمن تشکر دوباره :flower: 
طبق توضیحات شما من کد رو به این صورت تغییر دادم
var
Dummy,lpBuffer:String
begin
  Repeat
     Application.ProcessMessages;
     SetLength(lpbuffer,1);
     ReadFile(hFile,Pchar(lpBuffer)^,nNumberOfBytesToRe ad,lpNumberOfBytesRead,nil);
     Dummy:=Dummy+lpBuffer;
     sleep(300);
  Until lpNumberOfBytesRead=0;
end;
  
گاهی بافر خالیه(یعنی lpNumberOfBytesRead=0) و گاهی عبارت   
  Pchar(lpbuffer)^     باعث میشه که خطای دسترسی غیرمجاز به حافظه رو بده  :sad2: 
وقتی هم از کامپوننت شما استفاده میکنم
var
 PortDrive:TCommPortDriver;
 Rs232:Trs232;
 Buffer:String;
begin
  Rs232.ComPort:=pnCOM3;
  Rs232.Connect;
  if Rs232.Connected then
   begin
    Application.ProcessMessages;
    RS232.SendString('ATI'+#13+#10); {Error: " RS232.SendString: Send not possible !"}
    RS232.ReadString(Buffer,10);
   end;
   ShowMessage(Buffer);
end;
خطای RS232.SendString: Send not possible رو میده  :sorry:
 
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.