加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

.NET相当于Delphi的IStream初始化

发布时间:2020-12-15 09:11:37 所属栏目:大数据 来源:网络整理
导读:我有以下Delphi代码: var Stream: TMemoryStream; StreamI: TStreamAdapter; OleStream: IStream;begin Stream:= TMemoryStream.Create; Stream.LoadFromFile(filename); StreamI:= TStreamAdapter.Create(Stream,soOwned); VSPDFViewer1.LoadStream(Stream
我有以下Delphi代码:

var
 Stream: TMemoryStream;
 StreamI: TStreamAdapter;
 OleStream: IStream;
begin

 Stream:= TMemoryStream.Create;
 Stream.LoadFromFile(filename);
 StreamI:= TStreamAdapter.Create(Stream,soOwned);
 VSPDFViewer1.LoadStream(StreamI as IStream,'');
end;

它实际上将一个IStream对象传递给COM组件.
.NET有“System.Runtime.InteropServices.ComTypes.IStream”接口,但我无法找到使用它的正确方法.如何使用数据初始化IStream并将其传递给.NET中的COM对象?

解决方法

这有点糟糕,但你必须编写自己的.NET StreamAdapter类.幸运的是,您可以窃取Microsoft的所有代码:

public class StreamAdapter : System.Runtime.InteropServices.ComTypes.IStream
{
    // Fields
    protected Stream dataStream;
    private long virtualPosition = -1L;

    // Methods
    internal StreamAdapter(Stream stream)
    {
        if (!stream.CanSeek)
        {
            int num;
            byte[] sourceArray = new byte[0x100];
            int offset = 0;
            do
            {
                if (sourceArray.Length < (offset + 0x100))
                {
                    byte[] destinationArray = new byte[sourceArray.Length * 2];
                    Array.Copy(sourceArray,destinationArray,sourceArray.Length);
                    sourceArray = destinationArray;
                }
                num = stream.Read(sourceArray,offset,0x100);
                offset += num;
            }
            while (num != 0);
            this.dataStream = new MemoryStream(sourceArray);
        }
        else
        {
            this.dataStream = stream;
        }
    }

    private void ActualizeVirtualPosition()
    {
        if (this.virtualPosition != -1L)
        {
            if (this.virtualPosition > this.dataStream.Length)
            {
                this.dataStream.SetLength(this.virtualPosition);
            }
            this.dataStream.Position = this.virtualPosition;
            this.virtualPosition = -1L;
        }
    }

    public virtual System.Runtime.InteropServices.ComTypes.IStream Clone()
    {
        NotImplemented();
        return null;
    }

    public virtual void Commit(int grfCommitFlags)
    {
        this.dataStream.Flush();
        this.ActualizeVirtualPosition();
    }

    [SecurityPermission(SecurityAction.Assert,Flags=SecurityPermissionFlag.UnmanagedCode),UIPermission(SecurityAction.Demand,Window=UIPermissionWindow.AllWindows)]
    public virtual long CopyTo(UnsafeNativeMethods.IStream pstm,long cb,long[] pcbRead)
    {
        int num = 0x1000;
        IntPtr buf = Marshal.AllocHGlobal(num);
        if (buf == IntPtr.Zero)
        {
            throw new OutOfMemoryException();
        }
        long num2 = 0L;
        try
        {
            while (num2 < cb)
            {
                int length = num;
                if ((num2 + length) > cb)
                {
                    length = (int) (cb - num2);
                }
                int len = this.Read(buf,length);
                if (len == 0)
                {
                    goto Label_006C;
                }
                if (pstm.Write(buf,len) != len)
                {
                    throw EFail("Wrote an incorrect number of bytes");
                }
                num2 += len;
            }
        }
        finally
        {
            Marshal.FreeHGlobal(buf);
        }
    Label_006C:
        if ((pcbRead != null) && (pcbRead.Length > 0))
        {
            pcbRead[0] = num2;
        }
        return num2;
    }

    protected static ExternalException EFail(string msg)
    {
        throw new ExternalException(msg,-2147467259);
    }

    public virtual Stream GetDataStream()
    {
        return this.dataStream;
    }

    public virtual void LockRegion(long libOffset,int dwLockType)
    {
    }

    protected static void NotImplemented()
    {
        throw new ExternalException(SR.GetString("NotImplemented"),-2147467263);
    }

    public virtual int Read(IntPtr buf,int length)
    {
        byte[] buffer = new byte[length];
        int num = this.Read(buffer,length);
        Marshal.Copy(buffer,buf,length);
        return num;
    }

    public virtual int Read(byte[] buffer,int length)
    {
        this.ActualizeVirtualPosition();
        return this.dataStream.Read(buffer,length);
    }

    public virtual void Revert()
    {
        NotImplemented();
    }

    public virtual long Seek(long offset,int origin)
    {
        long virtualPosition = this.virtualPosition;
        if (this.virtualPosition == -1L)
        {
            virtualPosition = this.dataStream.Position;
        }
        long length = this.dataStream.Length;
        switch (origin)
        {
            case 0:
                if (offset > length)
                {
                    this.virtualPosition = offset;
                    break;
                }
                this.dataStream.Position = offset;
                this.virtualPosition = -1L;
                break;

            case 1:
                if ((offset + virtualPosition) > length)
                {
                    this.virtualPosition = offset + virtualPosition;
                    break;
                }
                this.dataStream.Position = virtualPosition + offset;
                this.virtualPosition = -1L;
                break;

            case 2:
                if (offset > 0L)
                {
                    this.virtualPosition = length + offset;
                    break;
                }
                this.dataStream.Position = length + offset;
                this.virtualPosition = -1L;
                break;
        }
        if (this.virtualPosition != -1L)
        {
            return this.virtualPosition;
        }
        return this.dataStream.Position;
    }

    public virtual void SetSize(long value)
    {
        this.dataStream.SetLength(value);
    }

    public void Stat(IntPtr pstatstg,int grfStatFlag)
    {
        STATSTG structure = new STATSTG();
        structure.cbSize = this.dataStream.Length;
        Marshal.StructureToPtr(structure,pstatstg,true);
    }

    public virtual void UnlockRegion(long libOffset,int dwLockType)
    {
    }

    public virtual int Write(IntPtr buf,int length)
    {
        byte[] destination = new byte[length];
        Marshal.Copy(buf,destination,length);
        return this.Write(destination,length);
    }

    public virtual int Write(byte[] buffer,int length)
    {
        this.ActualizeVirtualPosition();
        this.dataStream.Write(buffer,length);
        return length;
    }

    // Nested Types
    [StructLayout(LayoutKind.Sequential)]
    public class STATSTG
    {
        public IntPtr pwcsName = IntPtr.Zero;
        public int type;
        [MarshalAs(UnmanagedType.I8)]
        public long cbSize;
        [MarshalAs(UnmanagedType.I8)]
        public long mtime;
        [MarshalAs(UnmanagedType.I8)]
        public long ctime;
        [MarshalAs(UnmanagedType.I8)]
        public long atime;
        [MarshalAs(UnmanagedType.I4)]
        public int grfMode;
        [MarshalAs(UnmanagedType.I4)]
        public int grfLocksSupported;
        public int clsid_data1;
        [MarshalAs(UnmanagedType.I2)]
        public short clsid_data2;
        [MarshalAs(UnmanagedType.I2)]
        public short clsid_data3;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b0;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b1;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b2;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b3;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b4;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b5;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b6;
        [MarshalAs(UnmanagedType.U1)]
        public byte clsid_b7;
        [MarshalAs(UnmanagedType.I4)]
        public int grfStateBits;
        [MarshalAs(UnmanagedType.I4)]
        public int reserved;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读