lamurire pAnsiChar


mmx


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
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
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
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
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
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
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
*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 sleep.gif
mmx
Este totul ok, multumesc mult.
Aceasta este o versiune simplificatã a paginii originale. Pentru a vizita versiunea originala click aici.