所以,我有下面的问题。我有2个PChar变量。我首先分配内存,做一些操作,为第二个变量分配内存 - 在这一步,第一个变量包含坏值(我在调试时看到它)。这是代码:
procedure TReadThread.Execute;
Var
iRead, temp, i, count : Integer;
header, params : PChar;
begin
try
GetMem(header, 12);
iRead := recv(FSocket, header^, 12, 0);
if (iRead<>12) then
raise Exception.Create('Header recieving problem!');
temp := StrToIntDef(String(copy(header,3,4)),0);
if (temp=0) then
raise Exception.Create('Body receiving problem!');
count := temp*SizeOf(Char);
if (count+12<=16384) then
begin
GetMem(params, count);
iRead := recv(FSocket, params^, count, 0);
if (iRead<>count) then
raise Exception.Create('Cant recieve messsage fully!');
end
else
raise Exception.Create('Bad message size (>16 KB)!');
GetMem(FText, temp*SizeOf(Char)+12);
FText := PChar(String(header) + String(params));
FreeMem(header);
FreeMem(params);
except
on E : Exception do
ShowMessage(E.Message);
end;
end;
在线
iRead := recv(FSocket, params^, count, 0);
当我寻找变量HEADER值时 - 我看到了一些惊人的东西 - 当我在程序开始时看到它时不一样。我怎么解决它?
答案 0 :(得分:3)
我认为FText
是PChar
。既然您说您使用的是Delphi 2010,那么您应该知道Char
实际上是WideChar
的同义词,并且宽度为2个字节。我怀疑你真的想要使用AnsiChar
。
最明显的问题是您为FText
分配了内存,然后通过分配给FText
将其丢弃。更重要的是,当程序结束时,FText
引用的内存将被销毁。
我认为您应该执行以下操作:
AnsiChar
来recv
来电。FText
更改为AnsiString
。GetMem
并使用堆栈分配。也许是这样的:
procedure TReadThread.Execute;
Var
iRead, count: Integer;
header: array [0..12-1] of AnsiChar;
params: array [0..16384-1] of AnsiChar;
begin
try
iRead := recv(FSocket, header, 12, 0);
if (iRead<>12) then
raise Exception.Create('Header receiving problem!');
count := StrToIntDef(Copy(header,3,4),0);
if (count=0) then
raise Exception.Create('Body receiving problem!');
if (count+12<=16384) then
begin
iRead := recv(FSocket, params, count, 0);
if (iRead<>count) then
raise Exception.Create('Cant receive messsage fully!');
end
else
raise Exception.Create('Bad message size (>16 KB)!');
SetLength(FText, 12+count);
Move(header, FText[1], 12);
Move(params, FText[13], count);
except
on E : Exception do
ShowMessage(E.Message);
end;
end;
答案 1 :(得分:0)
AS David Heffernan说道。 Char是2字节,并且pChar指向Delphi 2010中的Unicode字符。但David的代码有2个问题
如果您想获得国际字符(unicode或utf8字符串),则无法使用AnsiChar
如果将params变量定义为AnsiChar的Array [0..16384-1],那么您将失去程序性能。局部变量将使用堆栈并定义params,就像David定义的那样会消耗你的堆栈空间。
您可以使用的答案通过1个简单的更改来使用您的代码。只将您的标题和参数变量定义为PAnsiChar。你可以把其他代码保持不变。
标题,参数:PAnsiChar;