locked
Is memory created by new Array() stable for WinRT components?

    Question

  • Is it safe to use the memory returned by this function in a WinRT component?

    getFileContentsAsync = function(storageFile) {
        return storageFile.openAsync(FileAccessMode.Read).then(function(fileStream) {
          var fileSize, inputStream, reader;
          inputStream = fileStream.getInputStreamAt(0);
          fileSize = fileStream.size;
          reader = new DataReader(inputStream);
          return reader.loadAsync(fileSize).then(function() {
            var array;
            fileStream.close();
            array = new Array(fileSize);
            reader.readBytes(array);
            reader.close();
            return array;
          });
        });

    The WinRT takes the memory in an synchronous call and reads from the memory. Is the memory guaranteed to stay at the same location or can the GC move it around? If it can, how do I lock the memory?

    And no, before anyone suggests it, there is no way to use the stream directly in the WinRT component, since legacy SDKs do not understand WinRT and its async approach.

    Thanks!

    Monday, April 2, 2012 2:48 PM

Answers

  • my WinRT Component is written in C++ so .net related services cannot be used.

    However I have fixed the whole thing by using the IBuffer interface and it works smoothly now. The WinRT component allocates an array of bytes that is automatically garbage collected.

    Windows::Storage::Streams::DataReader^ dataReader = Windows::Storage::Streams::DataReader::FromBuffer(buffer);
      auto data = ref new Platform::Array<uint8>(buffer->Length);
      dataReader->ReadBytes(data);
      

    Tuesday, April 3, 2012 1:12 PM

All replies

  • Hi Phil,
             Most managed types are going to be movable in the address space, including Array.  You'll want to research the use of pinned objects in .NET via System.RunTime.InteropServices.GCHandle.Alloc(Object, GCHAndleType) with GCHandleType.Pinned.  This will lock the object into an address as you request.  However, please keep in mind that it will make garbage collection inefficient since it will lose all of the address space that resides below it as usable space.


    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    Monday, April 2, 2012 5:55 PM
    Moderator
  • my WinRT Component is written in C++ so .net related services cannot be used.

    However I have fixed the whole thing by using the IBuffer interface and it works smoothly now. The WinRT component allocates an array of bytes that is automatically garbage collected.

    Windows::Storage::Streams::DataReader^ dataReader = Windows::Storage::Streams::DataReader::FromBuffer(buffer);
      auto data = ref new Platform::Array<uint8>(buffer->Length);
      dataReader->ReadBytes(data);
      

    Tuesday, April 3, 2012 1:12 PM
  • Sorry for that, I usually tend to the C# forums and didn't realize I was in the Javascript forum when I posted, especially since we started talking about GC.  I'm glad you got this resolved.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    Tuesday, April 3, 2012 1:27 PM
    Moderator
  • no problem, thanks for your support here!

    Any idea how the IBuffer/Reader is implemented? It uses very little RAM so I suspect its using memory mapped files behind the scenes?

    Tuesday, April 3, 2012 1:51 PM
  • Not really sure...

    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    Tuesday, April 3, 2012 3:50 PM
    Moderator