.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 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; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |