Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

allocating "unmanaged" memory in c#

Tags:

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

like image 666
Blitzz Avatar asked Apr 15 '10 19:04

Blitzz


People also ask

What is unmanaged memory?

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.

Is dynamic allocation slower?

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.

How do you malloc in C#?

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.

What is marshal AllocHGlobal?

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.


2 Answers

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.

like image 106
Andrew Hare Avatar answered Oct 25 '22 16:10

Andrew Hare


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.

like image 20
plinth Avatar answered Oct 25 '22 16:10

plinth