Reputation: 2224
I found out that there are a bunch of projects (SharpDX,etc) that are being compiled to allow CLR to "manage" the native code and then call that native code (c++ functions) straight from e.g.: c#.
I am trying to figure out how this works..and it would be nice if any of you out there knows.
What I have seen so far is that I can add the reference in a C# project to a "CLR compatible" C++ library just as any other c# library (without the need of reflection), adding it like : "using myCppLibrary" and then just call whatever methods are available on it.
When I went to see what functions where available on the reference I just added, it seems that I can access from c# anything that was declared as PUBLIC on the C++ library's header (.h) files since they are automatically converted into c# code by the compiler.
So actually what is going on is :
I declare public methods / variables in the header (.h) file in my c++ library. I compile them checking that CLR management is available in the properties tab of the library. (I am using Visual Studio 2012) The compiler generates c# classes for every header file (.h) with any public methods/properties on it.
But what I dont understand is how when I call lets say,the giveNumber() function from "myCppLibrary"..where is the implementation of that function carried out?
Does CLR inter-communicate with c++ native code automatically or what is actually going on?
Upvotes: 1
Views: 733
Reputation: 941337
Not so sure I understand exactly what you are seeing. But high odds that you are seeing the side-effect of a mistake. The C++/CLI compiler is capable of compiling any C++03 compatible native C++ code into IL. Both IL and jitter are flexible enough to support this. And just like the IL generated by, say, the C# compiler, this kind of IL will be translated to machine code at runtime and is optimized the exact same way.
This however does not make it managed code. Any objects created by this code are still native objects that get allocated in unmanaged memory, just like a native C++ compiler will do. The garbage collector is completely oblivious to them.
The mistake then is to allow that code to be translated to IL. You are missing out on the extra time that the C++ code generator can spend at compile time to find the best optimized machine code. The jitter optimizes too but it can't do quite as good a job, having to operate under time constraints. And of course you'll take the jitting overhead at runtime.
The native structs and classes will be visible in the assembly metadata. But they are just opaque value types without their members accessible to a C# program. You cannot directly call a method of such a native class from C#. To be usable, a C++/CLI program must declare types with the value or ref contextual keywords. Like ref class, the exact equivalent of a C# class.
So it is important that you compile native code to machine code, just like a regular C++ compiler does. You do so by compiling a .cpp source file without /clr in effect. Or by wrapping such code with #pragma unmanaged and #pragma managed, switching the compiler back and forth between machine code and IL generation. The value add you get from C++/CLI is that a method in a ref class can directly use native code without the kind of hassle you have to go through in C#, like pinvoke. And using native C++ classes, something you completely can't do from C#.
Upvotes: 3
Reputation: 8126
When you enable CLR in your C++, the compiler compiles the C++ code into IL rather than into native code. In this case, the C++, known as C++/CLI is augmented with various features to allow it to use the garbage collector, have fine control over whether garbage-collected memory is pinned to avoid it moving about, etc.
Writing C++/CLI is, in general, a specialist task, requiring knowledge of both C++ and C# (there are some subtle differences and pitfalls that can be made). It is in general recommended for interfacing between native and managed code, but it can be used to make whole libraries into .net.
Upvotes: 2