Reputation: 765
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
Upvotes: 26
Views: 50598
Reputation: 731
Years later, in the meantime: In .net6, 7, MS gifted us with the class "NativeMemory" with methods like "AlignedAlloc", which might be useful for vectorized applications: MS writes for this example:
public static void* AlignedAlloc (UIntPtr byteCount, UIntPtr alignment);
"This method is a thin wrapper over the C aligned_alloc API or a platform dependent aligned allocation API such as _aligned_malloc on Win32."
Of course, no garbage collection in that case. One has to release the memory oneself to avoid memory leaks, by using "AlignedFree".
Upvotes: 4
Reputation: 409
This is how we need to assign and free unmanaged memory by using specific number of bytes.
// Demonstrate how to call GlobalAlloc and
// GlobalFree using the Marshal class.
IntPtr hglobal = Marshal.AllocHGlobal(100);
Marshal.FreeHGlobal(hglobal)
Upvotes: 3
Reputation: 49189
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.
Upvotes: 9
Reputation: 351536
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.
Upvotes: 46