2010-04-06 12 views
19

Sto per scrivere un wrapper per un IStream di interoperabilità COM in modo che il codice che si aspetta un flusso .NET standard possa usarlo.Esiste già una classe wrapper per un IStream di interoperabilità COM?

Tuttavia, mi sembra che questo genere di cose possa essere già stato fatto prima (anche se non sono stato in grado di trovarlo da solo con la ricerca sul Web).

Quindi sto solo mettendo questo qui nel caso in cui sto per re-inventare la ruota.

Nota Ho trovato codice che implementa IStream che include uno stream .NET, ma ho bisogno del contrario.

risposta

33

Sì, System.Runtime.InteropServices.ComTypes.IStream. Un campione wrapper:

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); 
    } 
} 
+0

Grazie, questo è un ottimo antipasto per 10. – AnthonyWJones

+0

Grazie per questo. Una risposta davvero utile. –

+0

Come potrei andare sull'implementazione di 'Position'? Il consumatore del mio stream ne ha bisogno. –

Problemi correlati