我是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;
但出了点问题,我没有任何价值。你们知道我要做什么吗?
答案 0 :(得分:0)
您需要首先读取长度,然后读取UTF-8编码的字节。我根本不知道Oxygene,但代码可能是这样的:
var len: Integer:= 0;
aStream.&read(len) maxLength(sizeof(Integer));
var buf := new uint8_t[len];
aStream.&read(buf) maxLength(len);
我完全希望我的语法错误,但这是一般的想法!
答案 1 :(得分:0)
我认为您已经错误地转换了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 被声明为单个字节,并使用值变量的地址的类型转换进行初始化。 / p>
因此,如果值变量存储在内存地址 $ 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原始文件更直接可比。