10

In the midst of asking about manually managing CLR memory, I realized I know very little.

I'm aware that the CLR will place a 'cookie' on the stack when you exit a managed context, so that the Garbage Collector won't trample your memory space; however, in everything I've read the assumption is that you are calling some library written in C.

I want to an entire write layer of my application in C#, outside of the managed context, to manage data at a low level. Then, I want to access this layer from a managed layer.

In this case, will my Unmanaged C# code compile to IL and be run on the CLR? How does this work?

Community
  • 1
  • 1
kd8azz
  • 613
  • 5
  • 21
  • You make mention of writing unmanaged code in C#. I assume you mean that this is different than *calling* unmanaged code *from* C#. If so, I would like to see an example of what you mean. – Gerard Sexton Sep 12 '12 at 14:06
  • Based on oleksii's answer, what I was looking for simply does not exist. Thus, I am not really able to show you an example. – kd8azz Sep 12 '12 at 14:11

2 Answers2

15

I assume this is related to the same C# database project you mentioned in the question.

It is technically possible to implement an entire write layers in C/C++ or any other language. And it is technically possible to have everything else in C#. I am currently working on an application that uses unmanaged code for some high-performance low level stuff and C# for business logic and upper level management.

However, the complexity of the task shall not be underestimated. The typical way to do this, is to design a contract that both parties can understand. The contract will be exposed to the managed language and managed language will trigger calls to the native application. If you have ever tried calling a C++ method from C# you will get the idea... Plus every call to unmanaged code has quite significant performance overhead, which may kill the whole idea of low level performance.

If you really interested in high-performance relational databases, then use single low level language.

If you want to have a naive, but fully working implementation of a database, just use C#. Don't mix these two languages unless you fully understand the complexity. See Raven DB - a document based NoSQL databases that is fully built in C# only.

Will my Unmanaged C# code compile to IL and be run on the CLR?

No, there is no such thing as unmanaged C#. C# code will be always compiled into the IL code and executed by CLR. It is the case of managed code calling unmanaged code. Unmanaged code can be implemented in several languages C/C++/Assembly etc, but CLR will have no idea of what is happening in that code.

Update from a comment. There is a tool (ngen.exe) that can compile C# directly into native architecture specific code. This tool is designed to improve performance of the managed application by removing JIT-compilation stage and putting native code directly into the executable image or library. This code, however, is still "managed" by the CLR host - memory allocation and collection, managed threading, application domains, exception handling, security and all other aspects are still controlled by the CLR. So even though C# can technically be compiled into native code, this code is not running as a standalone native image.

How does this work?

Managed code interoperate with unmanaged code. There are couple of ways to do this:

  • Through the code via .Net Interop. This is relatively fast but looks a bit ugly in code (plus it is hard to maintain/test) (good article with C#/C/Assembly samples)
  • A much much slower approach, but more open to other languages: web wervices (SOAP, WS, REST and company), queueing (such as MSMQ, NServiceBus and others), also (possibly) interprocess communication. So unmanaged process sits on one end and a managed application sits on the other one.
oleksii
  • 35,458
  • 16
  • 93
  • 163
  • @oleksii- There is an exception to your remark _C# code will be always compiled into the IL code_. If using Microsoft's .Net implementation, there is a tool named ngen.exe that precompiles the IL code to native code, avoiding the overhead of just-in-time, IL->native code compilation that occurs the very first time a method or function is called. However, this might be counterproductive as ngen.exe must target a certain architecture in advance and the JIT compiler may use optimizations available for the platform actually running the code. Cheers! –  Sep 12 '12 at 18:07
  • @GerardSexton, sorry my initial remark was addressed to you instead of oleksii –  Sep 12 '12 at 18:09
  • @sgorozco thanks for the message anyway. I didn't know about ngen! – Gerard Sexton Sep 13 '12 at 02:31
  • 1
    @sgorozco Yeah that's true, I forgot about that one. I will update my answer. But from the other hand that code is still managed by CLR (there is simply no JIT compilation happening), for exmaple memory management and GC is controlled by CLR, exception handling goes through the standard CLR pipeline etc. – oleksii Sep 13 '12 at 14:04
1

I know this is a C# question, but if you are comfortable with C++, C++/CLI might be an option worth considering.

It allows you to selectively compile portions of your C++ code to either a managed or an unmanaged context - However be aware that code that interacts with CLR types MUST run in a managed context.

I'm not aware of the runtime cost of transitioning from managed-context to unmanaged-context and viceversa from within the C++ code, but I assume it must be similar to the cost of calling a native method via .net Interop from C#, which as @oleksii already pointed out, is expensive. In my experience this has really paid off if you need to interact frequently with native C or C++ libraries - IMHO it is much easier to call them from within a C++/CLI project rather than writing the required .net Interop interfaces in C#.

See this question for a litte bit of information on how it is done.

Community
  • 1
  • 1