【问题标题】:Load string from Delphi stream in Oxygene从 Oxygene 中的 Delphi 流加载字符串
【发布时间】:2014-07-27 12:53:20
【问题描述】:

我是 Oxygene 的新手,我想从 Delphi 生成的流中读取字符串。我通过 TCP 接收这个流。 以下是我如何将字符串保存到客户端的流中:

procedure SaveStringToStream(AStream: TStream; AString: String);
var
  StringSize: Integer;
  StringToSave: AnsiString;
begin
  StringToSave := Utf8Encode(AString);
  StringSize := Length(StringToSave);
  AStream.WriteBuffer(StringSize, SizeOf(StringSize));
  AStream.WriteBuffer(Pointer(StringToSave)^, StringSize);
end;

如您所见,我首先将字符串的大小添加到流中,然后添加内容。 我现有的从服务器端(Oxygene)的流中加载字符串的方法如下所示:

function LoadStringFromStream(const aStream: NSInputStream): String;
begin
  var buf: array[1024] of uint8_t;
  var len: Integer:= 0;   
  len := aStream.&read(buf) maxLength(1024);
  if len > 0 then
  begin    
    nslog(len.stringValue);
    var data: NSMutableData := NSMutableData.alloc().initWithLength(0);
    data.appendBytes(@buf) length(buf[0]); 

    exit NSString.alloc().initWithData(data) encoding(NSStringEncoding.NSASCIIStringEncoding);             
  end;    
end;

但这会返回孔的内容,而不是当前部分。

编辑: 哦,我在服务器应用程序中出错了……现在我可以读取字符串,但不能读取整数值(最多只能读取 256 位)。对于 Objective-C,我找到了这段代码

- (int32_t)readInt32
{
    int32_t value = 0;

    if ([self read:(uint8_t *)&value maxLength:4] != 4)
    {
        NSlog(@"***** Couldn't read int32");
    }
    return value;
}

那是氧气密码:

function readInt32(const aStream: NSInputStream): Integer;
begin
  var value: int32_t := 0;
  var tmp:= uint8_t(@value);
  if aStream.&read(@tmp) maxLength(4) <> 4 then
    NSLog('***** Couldn''t read int32');  
  exit value;
end;

但是出了点问题,我没有得到任何价值。你们知道我要做什么吗?

【问题讨论】:

    标签: delphi oxygene remobjects


    【解决方案1】:

    我认为您错误地转换了 Objective-C 代码(轻微但明显):

    function readInt32(const aStream: NSInputStream): Integer;
    begin
      var value: int32_t := 0;
      var tmp:= uint8_t(@value);
      if aStream.&read(@tmp) maxLength(4) <> 4 then
        NSLog('***** Couldn''t read int32');  
      exit value;
    end;
    

    在上面的代码中,tmp 被声明为单个字节,并使用 value 变量的 address 类型转换进行初始化。

    因此,如果 value 变量存储在内存地址 $12345678 (为简洁起见,将愚蠢的示例保留为 32 位)然后 tmp将使用值 $78 进行初始化。然后,您将 tmp 变量的地址传递给 aStream.read(),它会尝试将 4 个字节读入 tmp 变量的位置。 但是tmp只是一个1字节的值

    我认为您需要更改 tmp 的声明,使其成为指向 unit8_t指针,然后将其直接传递给 aStream.read()

      var value: int32_t := 0;
      var tmp:= ^uint8_t(@value);
      if aStream.&read(tmp) maxLength(4) <> 4 then
        NSLog('***** Couldn''t read int32'); 
    

    或消除 tmp 变量并直接传递 value 的地址,并使用适当的强制转换:

      var value: int32_t := 0;
      if aStream.&read(^uint8_t(@value)) maxLength(4) <> 4 then
        NSLog('***** Couldn''t read int32'); 
    

    后一种方法更直接地与 Objective-C 原始方法相媲美。

    【讨论】:

      【解决方案2】:

      您需要先读取长度,然后读取 UTF-8 编码的字节。我根本不知道Oxygene,但代码可能是这样的:

      var len: Integer:= 0;   
      aStream.&read(len) maxLength(sizeof(Integer));
      var buf := new uint8_t[len];
      aStream.&read(buf) maxLength(len);
      

      我完全认为我的语法有误,但这是大意!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-06
        • 1970-01-01
        • 1970-01-01
        • 2022-11-18
        • 1970-01-01
        相关资源
        最近更新 更多