C # and IStream.Read

I am trying to use System.Runtime.InteropServices.ComTypes.IStream from C #, but I am having problems. According to MSDN, the C # definition is as follows:

void Read(
    byte[] pv,
    int cb,
    IntPtr pcbRead
)

Basically, I can read data from the stream, but the above value of "pcbRead" is always "0" (although the byte array contains my data). While doing some reading, it seems that the pcbRead argument is a little harder to set up correctly (although I'm pretty new to C #).

Anyway, my code basically looks like this:

myPtr = (IntPtr)0;
int buffSize = 8192;
byte[] buffer = new byte[buffSize];
while (true)
{
  strm.Read(buffer, buffSize, myPtr);
  fs.Write(buffer, 0, myPtr.ToInt32());
  if (myPtr.ToInt32() < buffSize) break;
}

Again, the problem is that "myPtr" still contains "0" after reading, although the "buffer" seems to contain valid data.

+3
source share
3

. IStream:: Read() , . #, :

unsafe static int Read(System.Runtime.InteropServices.ComTypes.IStream strm,
  byte[] buffer) {
  int bytesRead = 0;
  int* ptr = &bytesRead;
  strm.Read(buffer, buffer.Length, (IntPtr)ptr);
  return bytesRead;
}

unsafe:

private static IntPtr ReadBuffer;

static int Read(System.Runtime.InteropServices.ComTypes.IStream strm,
  byte[] buffer) {
  if (ReadBuffer == IntPtr.Zero) ReadBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
  strm.Read(buffer, buffer.Length, ReadBuffer);
  return Marshal.ReadInt32(ReadBuffer);
}

, Marshal.CoTaskMemFree() .

+6

, , , . IStream.

.net, , .

using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace YourProject
{
  public static class IStreamExtensions
  {
    private const int bufferSize = 8192;
    public static MemoryStream ReadToMemoryStream(this IStream comStream)
    {
      var memoryStream = new MemoryStream();

      var amtRead = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
      Marshal.WriteInt32(amtRead, bufferSize);
      var buffer = new byte[bufferSize];
      while (Marshal.ReadInt32(amtRead) > 0)
      {
        comStream.Read(buffer, buffer.Length, amtRead);
        memoryStream.Write(buffer, 0, Marshal.ReadInt32(amtRead));
      }
      memoryStream.Position = 0;

      return memoryStream;
    }
  }
}

:

IStream istream = (IStream) someCOMclass.giveMeAStream();
MemoryStream netStream = istream.ReadToMemoryStream();
+1

IStream, , , .
myPtr . IntPtr ++, , , , myPtr.

?

unsafe 
{
    int pcbRead = 0;
    int buffSize = 8192;
    byte[] buffer = new byte[buffSize];
    while (true)
    {
        // taking address of pcbRead
        strm.Read(buffer, buffSize, new IntPtr(&pcbRead)); 
        fs.Write(buffer, 0, pcbRead);
        if (pcbRead < buffSize) break;
    }
}
0
source

Source: https://habr.com/ru/post/1726542/


All Articles