sharing memory between C# and native C++ - 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]

Related

How to Manage Memory with Unmanaged C/C++ from C#.net?

Need some expert advice:
I have an unmanaged code from a 3rd party provider which is on C/C++ and I am writing a wrapper from C#.Net to get referred and use the respective methods. Since its unmanaged and there is a lot of places which has the memory leak and unmanaged code is not known to manage the memory what is the best solution for this kind of scenario?
I have the solution with PInvoke and Marshalling which bridges the Managed and Unmanaged with a knowledge of taking the memory management. But will GC takes care of this completely or is there still a gap which the memory should be released? Is there a solution from the .Net wrapper class i have a generic way to manage the memory for the unmanaged calls?

Free managed memory allocation from unmanaged code

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.

managed and unmanaged

if a .net dll contains both managed and unmanaged code , how does the code will be converted to CIL and how CLR allocate and manages the memory
The unmanaged code is by definition not managed by the CLR. It will not be converted to CIL, and the CLR will neither allocate nor manage memory for it. That only happens for the managed code.
When you write unmanaged code in a .NET assembly, you're instructing the compiler and the run-time that you want to take matters into your own hands. You become responsible for memory management, just as if you were writing native code.

Is there a need to free memory in unmanaged code when it is loaded by managed code

There are 2 binaries. One is native/unmanaged C++ dll and other is managed c# exe. Now what I am doing is writing a function in c++ dll and allocated memory inside it using malloc. I exported this function to be used by my c# module.
In C++ I did:
char* FunctionHavingAllocatedMemory(int i){
char* p = (char*)malloc(100);
.....
//use p and do not free it.
return p;
}
In c# I did:
[DllImport("C++.dll")]
private static extern string FunctionHavingAllocatedMemory(int i);
Now, my question is: Is there any need to free memory in c++ module or c# module will automatically free it when function will return. Why I am thinking is since c# is managed module it will automatically cleanup the memory.
(Though it is good you free memory in c++ but I have certain constrained that I can not free memory in C++. Just wanted to understand more about managed applications and the way they handle memory management).
The garbage collector only works on the managed heap : the memory allocated in FunctionHavingAllocatedMemory is your responsibility to free.
Alternatively you could allocate the unmanaged memory in C# using Marshal.AllocHGlobal(), pass a pointer to it to your native dll and Marshal.FreeHGlobal() it back in C#. The Marshal class also has some functions to copy data into or fetch data from the allocated memory.
GC will responsible for managing memory for the managed code for unmanaged code you need to worry about how to reclaim memory.
i think , you can define a function in the c++ class which will internally release the memory.

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

Categories