簡體   English   中英

從Oxygene中的Delphi流加載字符串

[英]Load string from Delphi stream in Oxygene

我是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;
}

多數民眾贊成在Oxygene代碼:

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;

但是出了點問題,我沒有任何價值。 你們知道我該怎么辦嗎?

您需要先讀取長度,然后讀取UTF-8編碼的字節。 我一點都不了解Oxygene,但是代碼可能像這樣:

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

我完全希望自己的語法有誤,但這是總的想法!

我認為您錯誤地(但很明顯地)轉換了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被聲明為一個字節,並使用變量地址的類型強制轉換進行初始化。

因此,如果將變量存儲在內存地址$ 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變量並通過適當的強制轉換直接傳遞的地址:

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

后一種方法可以與Objective-C原始方法直接比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM