1

所以,我有以下问题。我有 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 值时——我看到了一些惊人的东西——与我在程序开始时看到的不同。我该如何解决?

4

2 回答 2

3

我想那FText是一个PChar. 既然您说您使用的是 Delphi 2010,您应该知道它Char实际上是同义词WideChar并且是 2 个字节宽。我怀疑你真的想使用AnsiChar.

最明显的问题是您为 分配内存FText,然后将其与分配给FText. FText更重要的是,当程序结束时,所引用的内存被破坏了。

我认为您可能应该执行以下操作:

  • 切换到AnsiChar通话recv
  • 更改FTextAnsiString.
  • 完全停止使用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;
于 2011-05-21T20:27:38.087 回答
0

正如大卫赫弗南之前所说。Char 是 2 字节,pChar 也指向 Delphi 2010 中的 Unicode 字符。但是 David 的代码有 2 个问题

  1. 如果要获取国际字符(unicode 或 utf8 字符串),则不能使用 AnsiChar

  2. 如果将 params 变量定义为 AnsiChar 的 Array [0..16384-1],那么您将失去程序性能。局部变量将使用堆栈并定义参数,就像 David 定义的那样会消耗您的堆栈空间。

对于答案,您可以通过 1 个简单的更改使用您的代码。仅将您的 header 和 params 变量定义为 PAnsiChar。您可以将其他代码保持不变。

标头,参数:PAnsiChar;

于 2011-06-28T08:33:25.950 回答