2010-04-06 27 views
19

Estoy a punto de escribir un Wrapper para una interoperabilidad COM IStream, de modo que el código que espera que un .NET Stream estándar pueda usarlo.¿Ya existe una clase contenedora para una interoperabilidad COM IStream?

Sin embargo, se me ocurre que este tipo de cosas ya se haya hecho antes (aunque no he podido encontrar yo mismo con búsquedas por Internet).

así que estoy poniendo esto aquí en caso de que estoy a punto de volver a inventar la rueda.

Nota He encontrado código que implementa IStream envolviendo una transmisión .NET pero necesito lo contrario.

Respuesta

33

Lo hace, System.Runtime.InteropServices.ComTypes.IStream. Un contenedor de muestra:

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

Gracias, eso es un gran comienzo para 10. – AnthonyWJones

+0

Gracias por esto. Una respuesta realmente útil. –

+0

¿Cómo podría implementar 'Posición'? El consumidor de mi flujo lo necesita. –

Cuestiones relacionadas