代码之家  ›  专栏  ›  技术社区  ›  AnthonyWJones

COM互操作IStream的包装类是否已存在?

  •  21
  • AnthonyWJones  · 技术社区  · 14 年前

    我将为COM互操作IStream编写一个包装器,以便期望使用标准.NET流的代码可以使用它。

    然而,我突然想到,这类事情以前可能已经做过(尽管我自己在网络搜索中找不到)。

    所以我把这个放在这里,以防我要重新发明轮子。

    注意,我遇到过实现IStream包装.NET流的代码,但我需要相反的代码。

    1 回复  |  直到 14 年前
        1
  •  35
  •   Hans Passant    14 年前

    确实如此, System.Runtime.InteropServices.ComTypes.IStream . 样品包装:

    using System;
    using iop = System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    
    public class ComStreamWrapper : System.IO.Stream {
      private IStream mSource;
      private IntPtr mInt64;
    
      public ComStreamWrapper(IStream source) { 
        mSource = source;
        mInt64 = iop.Marshal.AllocCoTaskMem(8);
      }
    
      ~ComStreamWrapper() { 
        iop.Marshal.FreeCoTaskMem(mInt64); 
      }
    
      public override bool CanRead { get { return true; } }
      public override bool CanSeek { get { return true; } }
      public override bool CanWrite { get { return true; } }
    
      public override void Flush() { 
        mSource.Commit(0); 
      }
    
      public override long Length { 
        get { 
          STATSTG stat;
          mSource.Stat(out stat, 1);
          return stat.cbSize;
        }
      }
    
      public override long Position {
        get { throw new NotImplementedException(); }
        set { throw new NotImplementedException(); }
      }
    
      public override int Read(byte[] buffer, int offset, int count) {
        if (offset != 0) throw new NotImplementedException();
        mSource.Read(buffer, count, mInt64);
        return iop.Marshal.ReadInt32(mInt64);
      }
    
      public override long Seek(long offset, System.IO.SeekOrigin origin) {
        mSource.Seek(offset, (int)origin, mInt64);
        return iop.Marshal.ReadInt64(mInt64);
      }
    
      public override void SetLength(long value) {
        mSource.SetSize(value);
      }
    
      public override void Write(byte[] buffer, int offset, int count) {
        if (offset != 0) throw new NotImplementedException();
        mSource.Write(buffer, count, IntPtr.Zero);
      }
    }