-1

I have a quite large float array (usually >40 million entries) which takes up between 150MB und 250MB megabytes in memory and I need to pass it to two different APIs. Both are thrid party tools which I can't change. One of which only accepts byte[] and the other one only ref float[].

It is not a problem for me to convert it to a byte[] using Buffer.BlockCopy or similar approaches. But due to memory fragmentation allocating an array of this size fails regularly, and I would like to avoid copying it if possible.

Is there any way, to accomplish this? Maybe using unsafe code or C++ cli or C++ or a combination of all of them? Or maybe using MemoryMappedFile? I have already tried all of these but so far without any success.

Botje
  • 26,269
  • 3
  • 31
  • 41
C. Göbeler
  • 65
  • 1
  • 8
  • 1
    Maybe, it's worth to mention that you have this problem in C# (as you tagged multiple languages). In C++, to reinterprete casting a float array to a byte array isn't a problem, IMHO. – Scheff's Cat Dec 19 '19 at 16:27
  • 1
    Are these different APIs *managed ones* (e.g. .Net assemblies) or *unmanaged* (say, dll which you address with a help of pInvoke)? – Dmitry Bychenko Dec 19 '19 at 17:09
  • I added a c++ Tag to the question because I know it would be possible in c++ and i think i could get a native Pointer to the First element in the managed float array, but i dont know how i would get a valid managed Byte Array from it. – C. Göbeler Dec 19 '19 at 21:34
  • The API which requires the Byte Array is managed and the one taking the float array is a RCW for a COM object. – C. Göbeler Dec 19 '19 at 21:36

2 Answers2

0

If I understood your question correctly, something like this:

GCHandle handle = GCHandle.Alloc(myObject, GCHandleType.Pinned);
try
{
    IntPtr myPinnedPointer = handle.AddrOfPinnedObject();
    // use myPinnedPointer for your needs
}
finally
{
    handle.Free();
}
Andrey Belykh
  • 2,578
  • 4
  • 32
  • 46
0

This question was previously tagged C++/CLI. In that context, byte[] is somewhat ambiguous, you could be referring to a unmanaged C-style array (which uses the [] syntax in C++/CLI), or you could be referring to a managed array (which uses the [] syntax in C#, but not in C++/CLI.)

Since the question is now tagged only C#, I'm assuming that when you say [], you're referring to managed arrays.

There is no way to make two managed arrays share the same memory.

If the two APIs you need to use are byte[] and float[] in C#, there's no way to make them share the memory. If one of the APIs took something lower-level, such as a byte*, there would probably be a way, but an array in C# is a full-fledged object, and the only thing it wants to do is allocate its own memory.

David Yaw
  • 27,383
  • 4
  • 60
  • 93