I'm writting a program in c# that uses a C++ library, and for some reason I need to allocate an unmanaged buffer to pass it to the lib. Is there a way to do this in c# ? Basically I would just need to do a malloc in C#...
Thanks
Unmanaged memory: memory allocated outside of the managed heap and not managed by Garbage Collector. Generally, this is the memory required by . NET CLR, dynamic libraries, graphics buffer (especially large for WPF apps that intensively use graphics), and so on. This part of memory cannot be analyzed in the profiler.
Dynamic memory allocation and deallocation are very slow operations when compared to automatic memory allocation and deallocation. In other words, the heap is much slower than the stack.
C# does not have, or use malloc in any way, shape or form. . NET applications are Managed: which means they have their own memory management built in (via the new keyword) and which is tied into the Garbage Collection system. They do not use malloc, or free as the memory is handled by the system for you.
AllocHGlobal(Int32) Allocates memory from the unmanaged memory of the process by using the specified number of bytes. AllocHGlobal(IntPtr) Allocates memory from the unmanaged memory of the process by using the pointer to the specified number of bytes.
Try something like this:
using System; using System.Runtime.InteropServices; class Example { static void Main() { IntPtr pointer = Marshal.AllocHGlobal(1024); } }
This uses the Marshal.AllocHGlobal
method:
Allocates memory from the unmanaged memory of the process by using the specified number of bytes.
You can also use a byte array for this.
You do this by using an unsafe routine and the fixed statement:
static unsafe void PerformOperation() { byte[] buf = new byte[1024]; fixed (void* ptr = &buf[0]) { SomeUnmanagedFunction(new IntPtr(ptr)); } }
The issue - and this is an important one - is that SomeUnmanagedFunction is not allowed to touch that pointer after it has returned and code has exited the fixed block. So if you do something like this:
static void PerformFabulousTrick() { byte[] buf = new byte[1024]; fixed (void *ptr = &buf[0]) { SetBuffer(ptr, buf.Length); } FillBuffer(); // puts data in buf - NOT - may crash hard }
you are asking for nothing but trouble. In this case you probably want to use a GCHandle, which can pin a managed object in the heap. This can also be troublesome in that you NEED to unpin it in a timely manner or you risk fragmenting your heap.
In general, I would recommend making sure that you're P/Invoking correctly into the function so that the maybe marshaller can do this work for you. I like fixed better than GlobalAlloc since its scope is clear. I can't decide which I like least of GlobalAlloc and GCHandle. Both require you to do more work since the GC or language won't do it for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With