Zunächst ist dies kein Duplikat von diesem Does a wrapper class for a COM interop IStream already exist?, weil ich die Implementierung in die andere Richtung brauche. Ich muss eine IStream-Implementierung von IO.Stream zu IStream erstellen. Aber bevor ich anfange, das zu tun, wollte ich fragen, ob jemand eine bereits existierende Implementierung oder irgendwelche Artikel darüber weiß. Ich konnte im .NET Framework nichts finden und google gab mir nur Ergebnisse von Implementierungen von IStream zu IO.Stream. Hat also jemand einen netten Tipp für mich? Ich weiß wirklich nicht, wie man startet, weil das erste Mitglied (Clone -> Erzeugt ein neues stream-Objekt, das auf die gleichen Bytes wie der ursprüngliche Stream verweist, aber einen separaten Suchzeiger auf diese Bytes liefert) Probleme macht. Ich habe keine Ahnung, wie man das auf Basis von IO.Stream macht.C# IStream Implementierung von IStream
8
A
Antwort
5
Schließlich habe ich es selbst getan (fühlen Sie sich frei, es zu kopieren und ändern):
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("0000000c-0000-0000-C000-000000000046")]
public interface IStream
{
[PreserveSig]
HResult Read([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] [Out] byte[] pv, int cb, IntPtr pcbRead);
[PreserveSig]
HResult Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbWritten);
[PreserveSig]
HResult Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition);
[PreserveSig]
HResult SetSize(long libNewSize);
HResult CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten);
[PreserveSig]
HResult Commit(int grfCommitFlags);
[PreserveSig]
HResult Revert();
[PreserveSig]
HResult LockRegion(long libOffset, long cb, int dwLockType);
[PreserveSig]
HResult UnlockRegion(long libOffset, long cb, int dwLockType);
[PreserveSig]
HResult Stat(out comtypes.STATSTG pstatstg, int grfStatFlag);
[PreserveSig]
HResult Clone(out IStream ppstm);
}
/// <summary>
/// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms752876(v=vs.85).aspx
/// </summary>
public class ComStream : Stream, IStream
{
private Stream _stream;
public ComStream(Stream stream)
: this(stream, true)
{
}
internal ComStream(Stream stream, bool sync)
{
if (stream == null)
throw new ArgumentNullException("stream");
if (sync)
{
stream = Stream.Synchronized(stream);
}
_stream = stream;
}
HResult IStream.Clone(out IStream ppstm)
{
//ComStream newstream = new ComStream(_stream, false);
//ppstm = newstream;
ppstm = null;
return HResult.E_NOTIMPL;
}
HResult IStream.Commit(int grfCommitFlags)
{
return HResult.E_NOTIMPL;
}
HResult IStream.CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
{
return HResult.E_NOTIMPL;
}
HResult IStream.LockRegion(long libOffset, long cb, int dwLockType)
{
return HResult.E_NOTIMPL;
}
HResult IStream.Read(byte[] pv, int cb, IntPtr pcbRead)
{
if (!CanRead)
throw new InvalidOperationException("Stream not readable");
int read = Read(pv, 0, cb);
if (pcbRead != IntPtr.Zero)
Marshal.WriteInt64(pcbRead, read);
return HResult.S_OK;
}
HResult IStream.Revert()
{
return HResult.E_NOTIMPL;
}
HResult IStream.Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
{
SeekOrigin origin = (SeekOrigin)dwOrigin; //hope that the SeekOrigin enumeration won't change
long pos = Seek(dlibMove, origin);
if (plibNewPosition != IntPtr.Zero)
Marshal.WriteInt64(plibNewPosition, pos);
return HResult.S_OK;
}
HResult IStream.SetSize(long libNewSize)
{
return HResult.E_NOTIMPL;
}
HResult IStream.Stat(out comtypes.STATSTG pstatstg, int grfStatFlag)
{
pstatstg = new comtypes.STATSTG();
pstatstg.cbSize = Length;
return HResult.S_OK;
}
HResult IStream.UnlockRegion(long libOffset, long cb, int dwLockType)
{
return HResult.E_NOTIMPL;
}
HResult IStream.Write(byte[] pv, int cb, IntPtr pcbWritten)
{
if (!CanWrite)
throw new InvalidOperationException("Stream is not writeable.");
Write(pv, 0, cb);
if (pcbWritten != null)
Marshal.WriteInt32(pcbWritten, cb);
return HResult.S_OK;
}
public override bool CanRead
{
get { return _stream.CanRead; }
}
public override bool CanSeek
{
get { return _stream.CanSeek; }
}
public override bool CanWrite
{
get { return _stream.CanWrite; }
}
public override void Flush()
{
_stream.Flush();
}
public override long Length
{
get { return _stream.Length; }
}
public override long Position
{
get
{
return _stream.Position;
}
set
{
_stream.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
return _stream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
_stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
}
protected override void Dispose(bool disposing)
{
if (_stream != null)
{
_stream.Dispose();
_stream = null;
}
}
}
Verwandte Themen
- 1. Implementierung von istream für einen Zeichenpuffer?
- 2. Initiiliaze IFilter von IStream
- 3. C++ Lösung istream :: tellg Warnung
- 4. Convert ifstream in istream
- 5. Manipulationen mit istream
- 6. Mit istream & als Funktionsparameter
- 7. istream für die Kommandozeileneingabe für C++/Poco
- 8. das Design von std :: istream Verstehen :: read
- 9. Vererben std :: iStream oder gleichwertig
- 10. IStream Lesen nach dem Versagen
- 11. Überladen >> mit iStream
- 12. Fast kontrollierte Kopie von istream zu ostream
- 13. Wie bekomme ich die Länge von IStream? C++
- 14. Drag & Drop von C# nach Windows Explorer mit IStorage/IStream
- 15. COM-Variante zu BLOB oder IStream serialisieren
- 16. Drag & Drop virtuelle Dateien mit IStream
- 17. Dlib deserialize Gesicht Form Modell mit iStream
- 18. Wie man Methode verspottet, die istream & zurückbringt?
- 19. FILE * und istream: verbinden Sie die beiden?
- 20. Wie implementiere ich seekg() für einen benutzerdefinierten istream/streambuf?
- 21. Direkt von einem std :: istream in einen std :: string lesen
- 22. So initialisieren Sie ein IMimeMessage-Objekt von IStream
- 23. Sollte istream :: peek() nicht immer zurückgeben, was Sie gerade putback()?
- 24. Warum verwendet fstream den istream-Prototyp des Operators nicht?
- 25. asio :: streambuf zu std :: istream verwirft neue Linie
- 26. So etwas wie istream :: getline() aber mit alternativen delim Zeichen?
- 27. Wie kann ich istringstream und ifstream einer istream-Variablen zuweisen?
- 28. Besserer Weg, um die Länge eines std :: istream zu bestimmen?
- 29. 1 Zeile von iStream nach String-Stream ohne temporäre Variable in C++ lesen?
- 30. Wie verwendet man DispCallFunc, um IStream :: SetSize (0) in Plain aufzurufen C
der COM-Client wird am Ende Aufruf :: Release() auf der IUnknown COM-Schnittstelle/CCW, aber es gibt keine Möglichkeit, das mit .Dispose() zu verbinden? – toong
Funktioniert nicht wie es ist, auch wenn es so aussieht: System.IO.Stream.Read() darf früh zurückkehren und sagen, dass es nicht alle Bytes gelesen hat, sondern nur einen oder mehrere. IStream :: Read() * always * liest alle angeforderten Bytes, bis das Ende des Streams erreicht ist. Unterschiedliche, inkompatible Verträge: Sie müssen eine Leseschleife in Ihrer Implementierung von IStream.Read() hinzufügen und den Puffer lesen/füllen, bis Sie entweder alle angeforderten Bytes erhalten haben oder nicht mehr zu lesen sind. –