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.
Related
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?
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]
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.
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.
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.