Friday, July 25, 2008

Delphi: Lettura dati da seriale

Lettura dati dalla porta seriale.

function Leggi(PortaCOM:String; Comando:String):String;
var str:string;
cmd, Buffer: Pchar;
hCom:Thandle;
ComStat: TComStat;
lpdcb:Tdcb;
bw,br:Dword;
Errors: DWORD;
begin
//Apro la porta
str := '';
hCom := CreateFile (pchar(PortaCOM),
GENERIC_READ + GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access*/
nil, // no security attrs */
OPEN_EXISTING, //* comm devices must use OPEN_EXISTING */ 0, //* not overlapped I/O */
0); //* hTemplate must be NULL for comm devices */ );
if (hCom = INVALID_HANDLE_VALUE) then

MessageBox(0, pChar('Impossibile aprire la porta seriale'), 'ATTENZIONE', MB_ICONSTOP or MB_OK)
else
if GetFileType( hCom ) <> FILE_TYPE_CHAR then
MessageBox(0, 'Attenzione errore apertura file', 'ATTENZIONE', MB_ICONSTOP or MB_OK)
else
Begin //Se tutto ok imposto i settaggi della porta: 9600:7:E:1
GetCommState(hCom, lpdcb);
lpdcb.BaudRate := Settaggi.BaudRate;
lpdcb.ByteSize := Settaggi.ByteSize;
lpdcb.Parity := Settaggi.Parity;
lpdcb.StopBits := Settaggi.StopBits;
SetCommState(hCom, lpdcb); //costruisco il comando da inviare alla porta
cmd := pchar(Comando);
bW := 0;
bR := 0;
str := ''; //Scrivo il comando sulla porta
WriteFile(hCom,cmd^,Length(Comando),bW,nil);
//Attendo 2 sec.
sleep(2000);
//Leggo i bytes nel buffer di input
ClearCommError(hCom, Errors, @ComStat);
if ComStat.cbInQue > 0 then
begin
//Alloco la memoria necessaria per memorizzare i bytes letti
GetMem(Buffer, ComStat.cbInQue);
//Leggo i bytes
ReadFile(hCom,Buffer^,ComStat.cbInQue,br,nil);
//trasferisco il buffer in Str
setLength(str, br);
Move(Buffer^, PChar(str)^, br);
//libero la memoria occupata dal buffer
FreeMem(Buffer);
end;
end;
closeHandle(hcom);
result:=str;
end;

Inseressante la funzione ClearCommError che consente di sapere i byte in attesa di essere scaricati. Questa funzione aspetta che sulla COM siano presenti i Byte riportati dalla funzione prima di uscire dal ReadFile.

Thursday, May 08, 2008

Confronto Java - C#

Interessante confronto a questo link

Tuesday, April 22, 2008

YUGOP

Il sito più bello di internet!
Da vedere lo storico.

Friday, April 04, 2008

Eval e Persistenza in Delphi

Ho affrontato un progetto in ACCESS molto interessante e per il quale ho usato la funzione Eval. Per chi non lo sapesse, questa funzione riceve una stringa e ne fa la valutazione. Per esempio Eval("2 + 3") ritorna 5.
Come stringa si può passare anche il nome di una funzione scritta da noi purchè con visibilità Public.

A questo punto mi sono chiesto come si potesse fare una cosa simile in Delphi, cioè chiamare una funzione usando il suo nome.
Ho trovato un esempio molto pertinente su About.com. Funziona a queste condizioni:
1. La procedura/funzione deve essere un metodo di una classe
2. Deve essere published (vedi punto 3)
3. La classe deve essere derivata da TPersistent o deve essere compilata con la direttiva {M+}

In Delphi è necessario che la classe abbia le informazioni di runtime (RTTI) per i metodi che si vogliono richiamare usando il loro nome. Le informazioni recuperabili tramite RTTI sono altrettanto utili per implementare la Persistenza, cioè la capacità di salvare lo stato degli oggetti creati all'interno di un programma.

Altri link interessanti sulla RTTI:
1. IMetal
2. Delphi Power Unleashed
3. Vari post sul Hallvard's Blogs come questo.