Delphi 如何将IStream转换为TStreamAdapter?

Delphi 如何将IStream转换为TStreamAdapter?,delphi,com,interface,delphi-7,istream,Delphi,Com,Interface,Delphi 7,Istream,如何在Delphi7上将IStream转换为TStreamAdapter 在Delphi XE2上,我可以写: var aStream: IStream; aStreamAdapter: TStreamAdapter; begin ... aStreamAdapter := aStream as TStreamAdapter; ... end; 但Delphi7写道: Error: Operator not applicable to this operand type

如何在Delphi7上将IStream转换为TStreamAdapter

在Delphi XE2上,我可以写:

var
  aStream: IStream;
  aStreamAdapter: TStreamAdapter;
begin
  ...
  aStreamAdapter := aStream as TStreamAdapter;
  ...
end;
但Delphi7写道:

Error: Operator not applicable to this operand type

这段代码之所以有效,是因为D2010中引入了一个新特性,即能够恢复对实现接口的对象的引用。但是请注意,如果
IStream
不是由Delphi代码实现的,那么cast将失败

如果您需要在旧版本的Delphi中引用实现对象,那么您将需要使用各种黑客之一来恢复它。例如:


但是,您不需要返回到实现对象。事实上,您确实想这样做是一个非常强烈的迹象,表明您的设计是错误的

该代码之所以有效,是因为D2010中引入了一个新特性,即能够恢复对实现接口的对象的引用。但是请注意,如果
IStream
不是由Delphi代码实现的,那么cast将失败

如果您需要在旧版本的Delphi中引用实现对象,那么您将需要使用各种黑客之一来恢复它。例如:

但是,您不需要返回到实现对象。事实上,您确实想这样做是一个非常强烈的迹象,表明您的设计是错误的

AxCtrls单元有一个对象来实现这一点

var
  aStream: IStream;
  bStream: TStream;
begin
  bStream := TOleStream.Create(aStream);
  try
    //
  finally
    bStream.Free;
  end;
end;
AxCtrls单元有一个对象来实现这一点

var
  aStream: IStream;
  bStream: TStream;
begin
  bStream := TOleStream.Create(aStream);
  try
    //
  finally
    bStream.Free;
  end;
end;
示例代码:

var
  aFileStream: TFileStream;
  iStr: TStreamAdapter;
  iRes , iRes1, iRes2: Largeint;
  aStreamStat: TStatStg;
  aStreamContent: IStream;
begin
  aFileStream := TFileStream.Create('<...>', fmCreate);
  try
    aStreamContent := <...> as IStream;
    aStreamContent.Seek(0, 0, iRes);
    iStr := TStreamAdapter.Create(aFileStream, soReference);
    aStreamContent.Stat(aStreamStat, 1);
    aStreamContent.CopyTo(iStr, aStreamStat.cbSize , iRes1, iRes2);
  finally
    aFileStream.Free;
  end;
end;
var
aFileStream:TFileStream;
iStr:TStreamAdapter;
iRes,iRes1,iRes2:大容量;
aStreamStat:TStatStg;
Astream内容:IStream;
开始
aFileStream:=TFileStream.Create(“”,fmCreate);
尝试
aStreamContent:=作为IStream;
aStreamContent.Seek(0,0,iRes);
iStr:=TStreamAdapter.Create(aFileStream,sorreference);
aStreamContent.Stat(aStreamStat,1);
aStreamContent.CopyTo(iStr、aStreamStat.cbSize、iRes1、iRes2);
最后
免费的;
结束;
结束;
示例代码:

var
  aFileStream: TFileStream;
  iStr: TStreamAdapter;
  iRes , iRes1, iRes2: Largeint;
  aStreamStat: TStatStg;
  aStreamContent: IStream;
begin
  aFileStream := TFileStream.Create('<...>', fmCreate);
  try
    aStreamContent := <...> as IStream;
    aStreamContent.Seek(0, 0, iRes);
    iStr := TStreamAdapter.Create(aFileStream, soReference);
    aStreamContent.Stat(aStreamStat, 1);
    aStreamContent.CopyTo(iStr, aStreamStat.cbSize , iRes1, iRes2);
  finally
    aFileStream.Free;
  end;
end;
var
aFileStream:TFileStream;
iStr:TStreamAdapter;
iRes,iRes1,iRes2:大容量;
aStreamStat:TStatStg;
Astream内容:IStream;
开始
aFileStream:=TFileStream.Create(“”,fmCreate);
尝试
aStreamContent:=作为IStream;
aStreamContent.Seek(0,0,iRes);
iStr:=TStreamAdapter.Create(aFileStream,sorreference);
aStreamContent.Stat(aStreamStat,1);
aStreamContent.CopyTo(iStr、aStreamStat.cbSize、iRes1、iRes2);
最后
免费的;
结束;
结束;

您需要使用
Create
方法,如

var StreamAdapter:TStreamAdapter;
begin
  StreamAdapter := TStreamAdapter.Create(aStream);
...

您需要使用
Create
方法,如

var StreamAdapter:TStreamAdapter;
begin
  StreamAdapter := TStreamAdapter.Create(aStream);
...


我能想到的想要这样做的唯一可能的原因是访问
TStreamAdapter.Stream
属性,因为您以前包装了
TStream
对象,现在想要它回来。如果这就是您正在做的,那么您应该将
TStream
引用存储在以前的某个地方,这样您就不必通过
IStream
接口来恢复它。从
IStream
获取
TStream
引用的正确方法是创建一个.Dup:Dup:Voted to closeNot duplicate,因为我有确切的接口和类。还有另一个解决问题的好方法。我想做这件事的唯一可能的原因是访问
TStreamAdapter.Stream
属性,因为您以前包装了
TStream
对象,现在想要它回来。如果这就是您正在做的,那么您应该将
TStream
引用存储在以前的某个地方,这样您就不必通过
IStream
接口来恢复它。从
IStream
获取
TStream
引用的正确方法是创建一个.Dup:Dup:Voted to closeNot duplicate,因为我有确切的接口和类。还有另一个解决问题的好方法。不,不是这个。问题中的代码恢复了实现接口的对象的对象引用。话虽如此,另一个答案表明预期的问题是“如何从IStream复制到TStream?”这是答案。不,不是这个。问题中的代码恢复了实现接口的对象的对象引用。话虽如此,另一个答案表明预期的问题是“如何从IStream复制到TStream?”这是答案。您误读了这个问题。post希望返回到实现接口的对象,而不是转换为接口。请看@David的答案。@Ken讽刺地说,这个答案来自提问者!也许这就是Altaveron实际问题的解决方案,但这并不是问题的答案。@David:是的,我没听清楚海报的名字。非常奇怪也许Altaveron需要编写更好的问题?这段代码还可以快速轻松地处理创建的
TStreamAdapter
实例。适当的方法是将
iStr
声明为
IStream
。感谢您的帮助。但是有一个没有黑客的有效解决方案。iStr与IStream的内容一致。我不确定是否需要给iStr.Free打电话。你误读了这个问题。post希望返回到实现接口的对象,而不是转换为接口。请看@David的答案。@Ken讽刺地说,这个答案来自提问者!也许这就是Altaveron实际问题的解决方案,但这并不是问题的答案。@David:是的,我没听清楚海报的名字。非常奇怪也许Altaveron需要编写更好的问题?这段代码还可以快速轻松地处理创建的
TStreamAdapter
实例。适当的方法是声明