【问题标题】:How do I convert an IntPtr to a Stream?如何将 IntPtr 转换为 Stream?
【发布时间】:2010-09-07 17:34:42
【问题描述】:
class Foo
{
   static bool Bar(Stream^ stream);
};

class FooWrapper
{
   bool Bar(LPCWSTR szUnicodeString)
   {
       return Foo::Bar(??);
   }
};

MemoryStream 将采用 byte[],但我喜欢尽可能不复制数据。

【问题讨论】:

    标签: .net c++ interop managed-c++


    【解决方案1】:

    如果您改用UnmanagedMemoryStream(),则可以避免复制(.NET FCL 2.0 及更高版本中存在类)。与MemoryStream 一样,它是IO.Stream 的子类,具有所有常见的流操作。

    微软对该类的描述是:

    提供从托管代码对非托管内存块的访问。

    这几乎可以告诉您您需要知道的内容。请注意,UnmanagedMemoryStream() 不符合 CLS。

    【讨论】:

    • 注意:这个答案只适用于不安全的代码。如果您不使用 unsafe 标志进行编译,则可以通过将数据编组到字节数组,然后将该字节数组包装在流中来获得更好的运气。请参阅此处:stackoverflow.com/a/11660831/684852 不过,您需要知道数据的长度(指针处原始 unicode 字符串中的字节数)。例如:byte[] dataArray = new byte[dataLength]; Marshal.Copy(szUnicodeString, dataArray, 0, dataLength); MemoryStream stream = new MemoryStream(dataArray);
    【解决方案2】:

    如果我必须复制内存,我认为以下方法会起作用:

    
    static Stream^ UnicodeStringToStream(LPCWSTR szUnicodeString)
    {
       //validate the input parameter
       if (szUnicodeString == NULL)
       {
          return nullptr;
       }
    
       //get the length of the string
       size_t lengthInWChars = wcslen(szUnicodeString);  
       size_t lengthInBytes = lengthInWChars * sizeof(wchar_t);
    
       //allocate the .Net byte array
       array^ byteArray = gcnew array(lengthInBytes);
    
       //copy the unmanaged memory into the byte array
       Marshal::Copy((IntPtr)(void*)szUnicodeString, byteArray, 0, lengthInBytes);
    
       //create a memory stream from the byte array
       return gcnew MemoryStream(byteArray);
    }

    【讨论】:

      猜你喜欢
      • 2017-09-09
      • 2013-08-12
      • 2016-12-07
      • 1970-01-01
      • 2010-10-20
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多