mmx
11th August 2009, 21:05
Rog si eu pe cineva sa ma lamureasca cu pAnsiChar.
Lucrez cu un component TComPort care la o versiune mai veche la functia pt citire respectiv scriere:
CODSURSA
comport.read(var:buffer,count:integer):integer;
respectiv
CODSURSA
comport.write(var:buffer,count:integer):integer;
la versiunea mai noua
CODSURSA
comport.read(buffer:pAnsiChar,count:integer):integer;
respectiv
CODSURSA
comport.write(const buffer:pAnsiChar,count:integer):integer;
Cu versiunea veche lucram:
CODSURSA
var x:integer;
begin
comport1.read(x,1);
respectiv
comport1.write(1,1);
end;
Nu imi dau seama ce este pAnsiChar-ul asta,(am citit pe google ca e un pointer la valoarea AnsiChar).
Chestia e ca eu am nevoie sa citest din port byte.
Rog sa ma lamureasca cineva.
PS. Am mai gasit pegoogle aceeasi problema
ciuly
12th August 2009, 10:22
nu e aceeasi problema. acolo omul se confurnta cu un array.
din punct de vedere al memoriei, un ansichar, echivalent un char in delphi <=7 cel putin, este reprezentat pe 1 byte. deci 1 char este 1 unsigned byte=byte in delphi.
practic, c:char; b:byte;
c:=char( B );
b:=byte( c );
deasemenea delphio face conversiile intre string si pchar/pansichar unde e clar, explicit (de ex la constante) iar unde nu, il faci tu expliciti like so:
c:pchar; s:string;
c:=pchar(s);
dar, iti aduci aminte ca pchar este POINTER si deci sizeof(pchar)=4 (pe 32 biti si ar trebui sa fie 8 pe 64 dar n-am avut ocazia sa testez)
tot din acest motiv daca
s:='abc';
c:=pchar(s); aici c='a', c+1='b' (c+1=operatie de incrementare a pointerului), c+2='c' so c+3=#0
s[1]:='d'; aici c='d', c+1='b' samd.
in loc d epchar poti folosi pansichar si viceversa cat timp ti clar ca char este byte si nu word. de aceea exista distinctia de wide si ansi.
revenind. solutia la tine este ceva de genu:
b:byte;
comport.write(pchar( B ),1);
comport.read(pchar( B ),1);
ps: nu te sfatuiesc sa folosesti tipul integer (default 4 bytes) acolo unde vrei 1 byte si sa faci cast pt ca daca nus tii exact ce se intampla s-ar putea sa ai suprize. deci daca vrei byte, foloseste byte. daca vrei wrod, word, samd. si tine minte diferenta de little endian si big endian si de cum e un array in meemorie (cazul pchar/pansichar si cum e o variabila de tipul x. citeste prin help, fa experimente.)
mmx
12th August 2009, 12:25
ok, multumesc pt raspuns.
Intre timp am reusit sa rezolv cu:
comport1.write(char(x)); cu comport1.write(pchar(x)); am eroare de "Incompatible types char and AnsiChar"
la componentul vechi(TComPort delphi7) era totul ok, deci eu stiind ca controlerul urmeaza sa trimite 1 byte sau mai multi citeam:
x:byte;
comport1.read(x,1);
x:word;
comport1.read(x,2);
si fac ce operatii vreau cu valoarea returnata.
la componentul nou(TComPort4Beta pentru Delphi2009.) nu-i dau de cap cum sa returnez valoarea.
x:byte;
comport1.read(pchar(x),1); am eroare de "Incompatible types Char and AnsiChar"
comport1.read(char(x),1); am eroare de "Incompatible types Char and AnsiChar"
poate mai ai vreo idee?
ciuly
12th August 2009, 16:10
comport1.read(pansichar(x), 1);
eu am zis ca pchar si pansichar sunt echivlente de la d7 in JOS. semnul < inseamna mai mic. d2009 e mai mare ca D7. de multe ori mai mare.
mmx
12th August 2009, 16:37
ok, compilerul tace, dar la executarea codului primesc o eroare Access violation write of address 000000F0.
Poate ca nu accesez eu corect, dar la componentul vechi pe delphi 7 functiona perfect.
Alte idei daca mai ai?
Multumesc!
ciuly
13th August 2009, 00:55
pai in primul rand UNDE e av-u ala? cum arata linia d cod si cum sunt declarate variabilele folosite in ea. doar nut e astepti sa ghicesc ce ai tu acolo.
oricum, AVu al aimi sugereaza ca folosesti metoda unui obiect neinitializat (mare amajoritatea a cazurilor) sau un pointer la un record neinitializat samd.
mmx
13th August 2009, 11:01
OK, ieri nu prea am avut timp sa ma ocup de el, dar uite rezultatul:
CODE
var
aData:array[1..8] of pAnsiChar; // *1
pData:pAnsiChar; //*2
bData:byte; //*3
begin
Comport1.Open;
sleep(100);
SetBaudRate(5,dbseven,prodd);
TxData($56); //ComPort1.write(char($56));
sleep(2000);
SetBaudRate(9600,dbeight,prnone);
sleep(300);
TxData($75);
comport1.Read(x,1);
Deci cu ComPort1.read(aData[1],1); se compileaza, ruleaza fara probleme, se stocheaza ceva date in array dar nu stiu cum sa vizualizez/utilizez datele stocate . Eu am nevoie de Byte/Word/Dword.
Cu ComPort1.read(pAnsiChar(pData),1); sau ComPort1.read(pAnsiChar(bData),1); Se compileaza dar am AV de jos.
Multumesc!
ciuly
13th August 2009, 11:28
*2 iti da eroare pt ca pdata nu e initializat nicaieri.
*3 iti da eroare ca am gresit eu cand ti-am aratat typecastul.
CODE
var x:byte;
begin
read(pansichar(@x));
pansichar e un pointer. prin urmare la cast trebuie sa ii oferi un pointer sau un string. in exemplul meu gresit typecastul trata variabila ca fiind adresa si incerca sa acceseze informatiile de la adresa cu valoarea din x. care e mizerie aiurea prin memorie.
se intampla si la case mai mari
mmx
13th August 2009, 11:54
Este totul ok, multumesc mult.
Aceasta este o versiune simplificatã a paginii originale. Pentru a vizita versiunea originala
click aici.