Free managed memory allocation from unmanaged code - c#

I'd like to do Marshal.AllocHGlobal in managed code, fill it with data, and pass that memory block to unmanaged (C++) code that will then be responsible for freeing it.
Under the hood, Marshal.AllocHGlobal calls LocalAlloc (and, I'm guessing, LocalLock). But in order for the unmanaged code to call LocalFree, it needs the HLOCAL returned by LocalAlloc, which Marshal.AllocHGlobal doesn't provide.
I'm not necessarily restricted to using AllocHGlobal; the high level goal is to let the managed code allocate memory that the unmanaged code and then read and free.

This is not a handle, not since Windows version 3. Calling LocalFree() on the pointer is fine, as the Windows SDK article shows in its example. Marshal.AllocCoTaskMem and CoTaskMemFree() are the better mouse trap here.

Related

Memory Profiling through C#

I have a c# library that P/Invokes into an unmanaged library. I allocate resources in the unmanaged memory, send them to the managed code, make a copy and then send it back for freeing by the unmanaged code. This apparently is leaking memory, so i want to a quick way in c# to determine the currently allocated memory and which changes as we free memory.
I tried using Process.GetCurrentProcess().PagedSystemMemorySize64, it shows that i have a memory leak, but i want to make sure this property reflects that i freed the memory or not.
Thanks in advance.

sharing memory between C# and native C++

is there a way to share memory between managed and native code, just like memory mapped files (I'am using .Net 2.0, so MMF is not available in this version), I'am new to this .Net, so what is actually marshalling? I've done this for communication between managed and unmanaged code, but my question is during marshaling do we copy the memory portion of unmanaged to managed memory area, or we share the same address space, thus when we change a variable from unmanaged code, then the value is changed too in managed code?
This post is a useful start point to gain some ideas about Marshaling between Managed and Unmanaged Code
you can skip the part related to [InAttribute] and [OutAttribute]

Memory Management Of Unmanaged Component By CLR

I am having a little confusion , may be this question is very silly one.
where does the memory allocated for a unmanaged component?
In my .net code if i initiated an unmanaged component, where this component is going to be loaded and memory is allocated ?
How CLR marshall call between Managed and Unmanaged heap ?
EDIT
Thanks for your reply but what i am asking is say suppose i do a DLLIMPORT of User32.Dll , this is clearly a unmanaged dll and i call some function in User32.DLL now my question , how CLR marshall my call to this unmanged dll?
It starts out pretty easy. The pinvoke marshaller first calls LoadLibrary and passes the DLL name you specified, the DllImportAttribute.Value property. In your case, user32.dll is already loaded because it gets loaded by the .NET bootstrapper, its reference count just gets incremented. But normally the Windows loader gets the DLL mapped into the address space of the process so the exported functions can be called.
Next is GetProcAddress to get the address of the function to call, the DllImportAttribute.EntryPoint property. The marshaller makes a couple of tries unless you used ExactSpelling. A function name like "foo" is tested several possible ways, foo and fooW or fooA. Nasty implementation detail of Win32 related to the difference between Unicode and Ansi characters. The CharSet property matters here.
Now I need to wave hands a bit because it gets tricky. The marshaller constructs a stack frame, setting up the arguments that need to be passed to the exported function. This requires low level code, carefully excluded from prying eyes. Take it at face value that it performs the kind of translations that the Marshal class supports to convert between managed and unmanaged types. The DllImportAttribute.CallingConvention property matters here because that determines what argument value needs to be place where so that the called function can read it properly.
Next it sets up an SEH exception handler so that hardware exceptions raised by the called code can be caught and translated into a managed exception. The one that generates the more common one, AccessViolationException. And others.
Next, it pushes a special cookie on the stack to indicate that unmanaged code is about to start using stack. This prevents the garbage collector from blundering into unmanaged stack frames and interpret the pointers it finds there as managed object references. You can see this cookie back in the debugger's call stack, [Managed to Native Transition].
Next, just an indirect call to the function address as found with GetProcAddress(). That gets the unmanaged code running.
After the call, cleanup might need to be done to release memory that was allocated to pass the unmanaged arguments. The return value might need to be translated back to a managed value. And that's it, assuming nothing nasty happened, execution continues on the next managed code statement.
Unmanaged memory allocations come from the process heap. You are responsible for allocating/deallocating the memory, since it will not get garbage collected because the GC does not know about these objects.
Just as an academic piece of info expanding on what has been posted here:
There are about 8 different heaps that the CLR uses:
Loader Heap: contains CLR structures and the type system
High Frequency Heap: statics, MethodTables, FieldDescs, interface map
Low Frequency Heap: EEClass, ClassLoader and lookup tables
Stub Heap: stubs for CAS, COM wrappers, P/Invoke
Large Object Heap: memory allocations that require more than 85k bytes
GC Heap: user allocated heap memory private to the app
JIT Code Heap: memory allocated by mscoreee (Execution Engine) and the JIT compiler for managed code
Process/Base Heap: interop/unmanaged allocations, native memory, etc
HTH
Part of your question is answered by Michael. I answer the other part.
If CLR loaded into an unmanaged process, it is called CLR hosting. This usually involves calling an entry point in mscoree DLL and then the default AppDomain is loaded. In such a case, CLR asks for a block of memory from the process and when given, that becomes its memory space and will have a stack and heap.

Memory allocators for a native C++ library to be used by C#

I'm writing some native C++ code which needs to be called from C# (and I can't replace the C++ native code with C# code).
I found memory corruptions while allocating/deallocating some memory in the native C++ code using malloc/free. Then I used LocalAlloc/LocalFree and HeapAlloc/HeapFree and had the same problems.
The allocations/deallocations seem to be correct, and they happen in a separate thread, created by the native code.
I was wondering which is the best allocation strategy to use in a native C++ library called by C#
EDIT: found the problem: the problem wasn't in the allocation/deallocation code, but in some memory being written after being deallocated.
As long as the C# side of the code uses the compiler's /unsafe switch and the fixed keyword used for holding the buffer of data, I think you should be ok.
As to the question of your memory allocation, it may not be the C++ memory allocation code that is causing the problem, it could be the way how the C++ code is interacting with the driver...maybe using VirtualAlloc/VirtualFree pair as per the MSDN docs...
Edit: When you try to allocate the buffer to hold the data from the C++ side after interacting with the driver...possibly a race-condition or interrupt latency is causing a memory corruption...just a thought...
Hope this helps,
Best regards,
Tom.
Your question is missing essential details, it isn't at all clear whether the memory allocated by the C++ code needs to be released on the C# side. That's normally done automatically with, say, the P/Invoke marshaller or the COM interop layer in the CLR. Or can be done manually by declaring a method argument as IntPtr, then use of the Marshal class.
If it is done automatically you must use the COM memory allocator, CoTaskMemAlloc(). If you marshal yourself you could also use GlobalAlloc(), release on the C# side with Marshal.FreeHGlobal(). There isn't any advantage to using GlobalAlloc(), you might as well use CoTaskMemAlloc() and release with Marshal.FreeCoTaskMem().
But you should have noticed this yourself. Allocating with malloc() or HeapAlloc() on the C++ side causes leaks instead of corruption if the managed code releases the memory. Vista and Win7 have a much stricter heap manager, it terminates the program if it notices a bad release.
It sounds to me that you have simple heap corruption in your C++ code. That is the most common scourge of unmanaged C++ programming, over-running the end of a buffer, writing to memory that's been freed, bad pointer values. The way to get rid of bugs like these is a careful code review and use of a debug allocator, such as the one provided by <crtdbg.h>. Good luck with it.
The windows driver developpement kit recommend against the use of C++ for drivers.
Also the best strategy is to have the driver manage its own memory. When the c# needs to see the data then pass it a marshalled buffer and have the driver to fill it

C# deallocate memory referenced by IntPtr

I am using some unmanaged code that is returning pointers (IntPtr) to large image objects. I use the references but after I am finished with the images, I need to free that memory referenced by the pointers. Currently, the only thing that frees the memory is to shutdown my entire app. I need to be able to free that memory from inside my application.
Here is the call to that allocates the memory. hbitmap is the pointer that is returned and needs to be deallocated.
[DllImport("twain_32.dll", EntryPoint = "#1")]
public static extern TwainResult DsImageTransfer(
[In, Out] Identity origin, [In] Identity dest, DataGroup dg,
DataArgumentType dat, Message msg, ref IntPtr hbitmap);
You need to use the specific memory allocator mechanism that was used to allocate the memory in the first place.
So, if you were using COM and the IMalloc interface to allocate the memory, then you have to pass the IntPtr back to the Free method on that implementation in order to free the memory allocated.
If you are indeed using the COM allocator that is returned by a call to CoGetMalloc, then you can call the static FreeCoTaskMem method on the Marshal class.
The Marshal class also has a method for freeing memory that is allocated through a call to LocalAlloc called FreeHGlobal.
However, and this is a common case, if the memory was allocated by the new operator in C++, or a call to malloc in C, then you have to expose a function in unmanaged code through interop which will free the memory appropriately.
In the case of C++, you would expose a function that takes a pointer and simply calls delete on that pointer. In the case of malloc, you would create a function that takes a pointer, and calls free on that pointer.
In specific regards to your question, it would seem that DsImageTransfer is a vendor-specific API (one that doesn't have much discoverability on the web either, I'm afraid), so more information is needed about that specific API function and how it allocates memory. Just knowing the handle type (an HBITMAP in this case) doesn't give any indication as to how it's allocated. It can be allocated with all the mechanisms mentioned above.
Assuming it is creating the HBITMAP using GDI Object api functions (specifically, the CreateBitmap function), then you could use the DeleteObject function to release the handle (as per the documentation page for the GDI Object API functions).
That would depend on how that memory was allocated. The Marshal class has methods for deallocating memory allocated through the common interop allocation patterns, like FreeCoTaskMem. If the unmanaged code uses a non Interop compatible way of allocating, then you cannot interop with it.
Updated
If I would venture a guess, the function #1 you invoke in twain_32.dll is the DS_ENTRY function in a TWAIN provider. The Twain specifications call out the memory resource management protocol:
Memory Management in TWAIN 2.0 and
Higher
TWAIN requires Applications and
Sources to manage each other’s memory.
The chief problem is guaranteeing
agreement on the API’s to use. TWAIN
2.0 introduces four new functions that are obtained from the Source Manager
through DAT_ENTRYPOINT.
TW_HANDLE PASCAL DSM_MemAllocate (TW_UINT32)
PASCAL DSM_MemFree (TW_HANDLE)
TW_MEMREF PASCAL DSM_MemLock(TW_HANDLE)
void PASCAL DSM_MemUnlock(TW_HANDLE)
These functions correspond to the
WIN32 Global Memory functions
mentioned in previous versions of the
TWAIN Specification: GlobalAlloc,
GlobalFree, GlobalLock, GlobalUnlock
On MacOS/X these functions call
NewPtrClear and DisposePtr. The lock
and unlock functions are no-ops, but
they still must be called. TWAIN 2.0
compliant Applications and Sources
must use these calls on all platforms
(Windows, MacOS/X and Linux). The
Source Manager takes the
responsibility to make sure that all
components are using the same memory
management API’s.
So to free resources you're supposed to call DSM_MemFree, which supposedly on Win32 platforms would be implemented through GlobalFree, or Marshal.FreeHGlobal.
Since this is mostly speculation on my part, you better validate with the specs of the specific TWAIN implementation you use.
It depends. Do you have any documentation (or source code) for the native functions you are calling?
Native code doesn't have a single deallocation function. This is one of the great advantages of the CLR.
If I was a betting man, I'd go for GlobalFree. But it's not going to be much fun trying various APIs until your code stops crashing.
Please show your unmanaged code. There are different ways to allocate memory in unmanaged land, and you must use the correct corresponding means of deallocating. You will probably end up implementing a Finalizer and IDisposable, and implementing the Dispose pattern as described here: http://www.codeproject.com/KB/cs/idisposable.aspx
Perhaps you could try creating a Bitmap object from hBitmap and then disposing it.
Bitmap bitmap = Bitmap.FromHBitmap(hBitmap);
bitmap.Dispose();
As everyone else is pointing out, It dpends on how it was allocated. However, if it really is a Win32 hbitmap, then you deallocate it with the Win32 "DeleteObject" function.

Categories