还是做点笔记,否则老忘,重复劳动。
使用TMemoryStream的Write方法时如果直接使用string作为参数,会出现莫名其妙的问题,Write方法实际把另一块不知道哪里冒出来的内存中的内容复制到了Stream的Memory里。假设lStr的地址为1,执行以下语句:
AStream.Write(lStr,Length(lStr) + 1);
Write方法实际执行时会把内存中自地址100起Length(lStr) + 1字节的内容写到AStream的Memory中。
Write方法的原型
function TMemoryStream.Write(const Buffer; Count: Longint): Longint;
经调试发现原因是这样的:
string类型实际为一个指针,其中存放了字符串存放的实际地址(其实这个早就知道,用的时候想当然了,所以导致现在的问题)。
结果就是,如果直接使用lStr变量,那么Write的Buffer参数获取的是lStr变量,它和lStr占用同一个4字节的内存空间,存放实际字符串的地址,如果Write方法知道这是个string类型,当然就没什么问题,可以强制进行转换,问题是,Write方法认为buffer中就存放着需要写到流中的内容,那就麻烦了,调试时看到的地址100其实就是变量lStr的地址,而1是字符串的真实地址。
正确的调用方法是:
AStream.Write(PChar(lStr)^, Length(lStr) + 1);
或者
AStream.Write(Pointer(lStr)^, Length(lStr) + 1);
这保证了Buffer就是实际字符串所在的内存区域。
此外,发现string在内存中也是用0作为结束符的,这和以前知道的不太一样,如果这样的话,不就和PChar统一起来了吗,也就不必区分null-terminated string和一般的delphi string。(怪里怪气的)