Native C++ performance using C# or within C# - c#

I was wondering if the two following scenarios have the same performance impact on native C++ code (if there is any performance impact at all).
Let's assume I have the function cpp_calc() that is doing some calculation stuff and is written in native C++. Also, there is cs_show_gui_stuff(), which is written in C#.
Now, which of the following scenarios will worsen the native c++ performance (if there is any performance penalty at all)?
Creating a .Net (C#) application that runs cs_show_gui_stuff() and calls cpp_calc() in the native C++ dll using DllImport or turning C++ into a COM DLL.
Creating a C++ application that implements cpp_calc() in C++ and runs cs_show_guid_stuff() by placing the C# code in a .Net COM DLL.
Thanks :-)

It really depends on what the other parts of the system are mainly written in. From a performance-only perspective, one PInvoke (via DllImport attribute) call will probably be faster than one COM call if the method arguments do not need any special marshaling.
A third, and probably the best alternative, is to create a managed C++/CLI library that calls the unmanaged C++ method with nearly no performance impact and add a reference to the C++/CLI library in the C# application. The C# application can then make managed method calls to the C++/CLI application, which in turn can make unmanaged method calls. While this adds one level of indirection, it will provide way better performance than the methods you mentioned.

Either way You are going to bump on Just-In-Time compiler. I guess the penalty is the same on both scenarios. I would personally choose the first one, because .NET libs are more robust on the GUI - WPF, Silverlight, WinForms, WebForms, Razor ... You see what I mean.

Related

Need advice in converting in one of the legacy C++ component into C#

Currently, we are working on a C++ legacy code base, which consists of several software components.
One of the components, are written in a way that is extremely difficult to maintain. (For example, memory allocation is done in X place, but memory de-allocation is done in Y place. This make memory management a painful job). Till now, we able to solve (or workaround) all the memory leakage issues.
However, after several rounds of bug fixing, our feeling is that, due to the high maintenance cost of this software component, we are unable to go too far from current milestone.
I know it might be bad to rewrite the source code : http://www.joelonsoftware.com/articles/fog0000000069.html
However, instead of re-factor the current code, we forsee it will be better to re-write from scratch due to
Till now, no one in the team can fully understand that software component code.
The legacy software component is a small piece of software. 20k lines, I guess
Our teams are pretty clear on the requirement and what we are trying to achieve
Hence, we are planning to go for a managed code, at least make memory management a painless job. We plan to choose C#, as
All our C++ code are compiled using Microsoft VC++
We are using MFC, in other software components. (in DLL form) Every DLL, do have their very own resource.
I am from C++ and Java background, and know nothing much on C#.
How well C# to interface with MFC DLL, with some of the DLL functions will invoke MFC GUI?
Anything I need to pay attention on it?
Will the interfacing with legacy C++ DLLs be easier, if we are using Managed C++?
Thanks.
I am in a similar situation and I also did some experiments mixing C++ and C#. The problems in my application however were that:
the application is not clearly split up in different modules, making it hard to move specific modules from C++ to C#
the application is quite cpu-intensive and experiments revealed a big overhead in calls from C++ to C# or C# to C++
Additionally, you cannot call C# directly from native/unmanaged C++, which meant that I had to introduce an additional intermediate C++/CLI (or is this called C++.Net?) layer.
Therefore, I chose not to move to C#, but stay with C++.
So, if you want to move from C++ to C#, make sure:
that you have clearly separated modules
that the transition (calls) from C++ to C# or vice versa are in a place that is not used that often (so not during cpu-intensive tasks)
Additionally, remember that if you are not the sole developer of the project, that all (or most) of your developers should also learn C#. You don't want to delegate all C# code to your latest junior developer, because if he leaves, you will be (or could be) in trouble.
How well C# to interface with MFC DLL, with some of the DLL functions will invoke MFC GUI?
Not well at all. You can't P/Invoke to a C++ library -- it works with C exports only. You would need to write a wrapper exposing a C library interface for you to P/Invoke from C#, or you'd need to recompile MFC using C++/CLI. There's little reason to do this though as Winforms is a comparable library to MFC for .NET code.
Anything I need to pay attention on it?
I don't understand that question.
Will the interfacing with legacy C++ DLLs be easier, if we are using Managed C++?
Considering you can't do it using C#, yes. You'd have to recompile those C++ DLLs to have them expose a C interface, or you'd have to recompile them from source using C++/CLI.
Note: No matter what you do here, you're still going to have to worry about memory managment and object lifetime of anything going on inside native code. The CLI does not automatically manage native resources for you.

Should I use Managed C++ or C# for my application?

If you had to decide between C# and Managed C++, which would you choose and why?
Are there benefits of Managed C++ over C#? Which language do you prefer? What decisions would you make under what circumstances?
I would use managed C++ if I:
Needed to integrate with existing C/C++ code
Needed to port existing C/C++ code to .net
Needed to use .NET objects from C++
Needed to expose .NET object over COM in a more complex way than what .net makes easy
Needed to access hardware directly
Needed to call lots of unmanaged APIs
And already had some skills in C++, as the above tasks will need a experienced C++ programmer. Most of the time I would only consider managed C++ if the company already had a C++ code base, otherwise who is going to maintain the managed C++ code.
In other cases I would always choose C#. Even if I choose managed C++ for part of the system, I would try to write as much of the system as possible in C#.
Think of manage C++ as a bridge building kit for going between the
unmanaged world of C/C++ and the
managed world of .NET.
If you only need to call a few simple APIs from C#, then see pinvoke.net and this overview to find how to call them from C#, as a few lines of complex pinvoke code (prebuilt bridge) in C# is normally better then introducing C++ to a project that is not already using it.
what is the benefit of managed C++
over C#?
C++.net is useful for interacting with C++ and C code (that is, calling external C or C++ libraries, providing callback functions to external modules written in C or C++ and so on.
what language of both would you
prefer?
I would prefer C# for all situations except the one described above (interacting with C and C++).
C# is easier to write, simpler, and geared specifically to use the .NET platform. C++ can do it also, but it has all the complexity of the C++ language plus the extensions needed to use the .NET platform.
Unless you need to interact with native C++ or C code, you're better off using C# in most cases (that is, if you're coding for the .NET platform).
Normally I prefer C++, but when needing to code for .NET, it doesn't beat C#.
Managed C++ is good for interop with C++: for example, if you have a .NET application and your assembly has to interact with a native interface that comes as C++ .lib files (which I had more than once), or with a nice C++ API.
Example: Rithmic (not that you ever heard of them) until recently ONLY supported a C++ API. If you try to access them from C# - good luck ;) Managed C++ allows me to access their API and expose nice .NET objects.
Basically interop. Managed C++ REALLY shines in interop with low level C / C++ API's.
I used managed C++ when I needed to build up new NET component with much ofC++ unmanaged code inside.
I did a specific class used to Marshall some objects forward and back from old C++ code.
I've encountered a problem which was transparent in managed C++, but made a big headache in C# - I had to send a callback function to a C++ unmanaged library, that defined this callback as __cdecl. In C#, the default calling convention is __stdcall, and it is pretty compilcated to move a C# delegate from __stdcall to __cdecl (Actually it requires either a 'shim' unmanaged DLL to do so or using some reflection classes).
In C++, (C++.Net as well), it is just a simple attribute.
I haven't personally written, or read for that matter, too many lines of code in managed C++, but from what I have seen it looks too convoluted and patchy. That said, you might want to use managed C++ if you are really good in C++, and when learning the idioms and patterns of a new language would be too much of a risk.
Use C# if you are quite competent in it. If you are only getting started with C++ and C#, I think, C# is the easier route to take.
I would prefer C#, or specifically .NET, over C++ because of the extensive .NET standard library.

What are the situations or pros and cons to use of C++/CLI over C#

I have been keeping up with .NET CLR for awhile now, and my language of choice is C#.
Up until recently, I was unaware that C++/CLI could produce "mixed mode" executables capable of running native and managed code.
Now knowing this, another developer friend of mine were discussing this attribute and trying to determine when and how this ability would be useful.
I take it as a given that native code has the capability to be more efficient and powerful than managed code, at the expense of additional development time.
In the past, I resorted to strictly native C++ code libraries and used Interop to make use of the functionality I wrote into the native library.
I can see the benefit of not requiring an additional library, but I'm curious as to what all the pros/cons of using C++/CLI over soley managed executable created in C#, or such an executable using Interop to call a purely native C++ library?
(Sidenote: Are the terms Interop/PInvoke interchangeable, as I d.on't understand the difference between the terms, simply seen them used the same way.)
With C++/CLI you can create, broadly speaking, three types of objects:
Managed types. These will compile down to essentially the same IL as the equivalent C#. There is no performance opportunity here.
Native types. Compiles down to native code as if you'd used straight C++.
Mixed mode types. These compile down to managed code, but allow you to refer to native types too.
You might think of (3) as being like writing C# code with PInvoke code to accessing the native stuff - except all the PInvoke stuff is generated for you.
There's more to it than that, of course, as well as some caveats - but that should give you an idea of how it's useful.
In other words it's really a glue language. While you can write fully fledged apps in C++/CLI it's more normal to keep the managed and native parts separate and use C++/CLI to bridge the two more cleanly than with PInvoke.
Another common use is to extend and existing, native, C++ code base with .Net library calls.
Just be careful that you partition your code well as it can be quite subtle sometimes in compiling your pure C++ code down to IL transparently!
As to your sidenote: PInvoke is a particular type of Interop. Interop comes in other forms too, such as COM Interop. In fact, more accurately, PInvoke is a set of language features that make Interop with native code easier.
I've used Managed C++ (the .NET 1.1 precursor to C++/CLI) effectively in the past. I find it works best when you have a native C or C++ library you wish to use in managed code. You could go the whole Interop/PInvoke route, which makes for some ugly C# code and frequently has marshalling issues, or you could write a managed C++ wrapper, which is where C++/CLI really shines.
Because C++/CLI is managed code, you can call it from C# (or VB.NET if you lean that way) in the normal way, by adding a reference to the .DLL. No marshalling, no dllimport, nothing goofy like that. Just normal project references. Additionally, you get the benefit of static linked libraries if your native library is so designed, which is a Good Thing (tm).
Phil Nash really hit the big things. Here's one more that I've hit more than once and is the primary reason I've used C++/CLI in the past:
Some applications are extended by checked all DLLs in some location for exported functions with a particular name. In C#, there's no way to declare a native C-style export, but you can in C++/CLI. I create a "wrapper" in C++/CLI that exports the method, handles any translation of C structs to managed objects and passes the call on to an assembly written in C#.
There are certain types that are not available to other languages, such as templates,
const and tracking handle of boxed value types.
templates are specialized at compile-time. generics are specialized at runtime. Although CLR should cache generics specialization for future use (so you get the same List each time you use it), there is still a performance hit each time a generics specialization is requested.
i know other languages discard the const attribute, but have compile time checking in your C++ code is better than nothing.
Having a type like int^ allows you to access the memory on the managed heap directory without unnecessary unboxing. This can help performance when passing tracking handles of boxed values to functions that expect a tracking handle, such as Console::WriteLine(Object^). Of course the early boxing initialization can not be avoided. In other languages you can store the reference in an Object variable and pass it around to avoid unboxing, but you lose the compile time type check.

How to use cross platform C++ with a WPF C# GUI

I'm currently in a project that need to work both on Mac and Windows. We are using standard portable C++ for all the application logic. However, since we want the app to feel totally native on both platform, the GUI will be written with C#/WPF for Windows and Objective-C/Cocoa for Mac.
However, for the windows part, I am wondering what is the best way to use the C++ code with C#. C# is managed, and I know that we can use managed C++ too. However I worry that using C++ inside the CLR may introduce unexpected bugs, or that we will need to put an awful lot of #ifdef WIN32 everywhere in the C++ code to make it work both with the managed CLR and the unmanaged environnement of Mac OS X (note that we sure expect to put some ifdef, but we'd like to keep it under control if possible). So basically, what is the best way to use the C++ code with the C# code? Right now, I'm thinking of three solutions
1- Compile the C++ as C++/CLI and directly use the classes and function from C#.
2- Compile and wrap the C++ in an unmanaged win32 dll and call it from C# using DllImport
3- Wrap the C++ in a COM wrapper and use the .NET COM Interop to link it with C#
Which one is the best way? Or, if there is a better solution, what is it?
C++/CLI has several restrictions over standard C++ that don't always make it easy to recompile standard C++ as C++/CLI. Keep in mind that you'll have to distinguish 'managed' and 'unmanaged' pointers, for starters. As these are using different symbols, you've got your first set of #ifdefs right there. And then you get to ref and value classes and all that sort of fun.
You can however use C++/CLI to bridge the gap between native code and the .NET world. The last time I did something along the lines of what you're planning to do, I used C++/CLI to write the bridging layer that did the necessary translation and conversion work between .NET types and classes and the native world. The C++/CLI layer can obviously be used from any .NET language.
You can't always use (2) - this depends very much on the data types you're trying to exchange between the two worlds. The .NET marshalling code is pretty good at dealing with C PODs but anything more complicated and you've got a problem.
(3) is overkill IMHO and introduces another point of failure, plus you're then doing .NET <-> COM <-> native instead of the simpler .NET <-> native if you created your own bridging code. Not to mention that you add complication to your code that won't benefit the other OS you're targeting, namely OS X.
Our development team has been using C++/CLI compiled code with ASP.NET and WPF front ends for while now.
The first major issue we had was build time. The code base would be 150k lines (40+ projects) and took forever to link (due to linker issues we could not build the individual projects as DLL's). We were only able to resolve this issue by wrapping the code with managed C++ classes and building our projects as assemblies.
The second major issue was performance. We originally compiled with /clr (before pure option existed) and this resulted in double thunking of most of our calls that occurred in the managed C++ layer. We fixed this by switching to /clr:pure. By doing so we ran into an
issue where our assemblies resulted in having too many 'global' methods in the assemblies so they would not load. We had to split our assemblies further to solve this issue.
Best and easier way is to do it with .NET <-> COM because COM has much stronger bridge compared to native dll access inside .NET because it may lead to lots of memory issues and lots of troubleshooting time. Its easier to test COM inside any MFC project and get the trace information for debugging and when the component is ready it can be easily used inside .NET.
CLI will not let you use all features and unfortunately its fairly new so less documentation is available and you will not get good support for your questions.
Win32 dll and DLLImport has problems mainly to troubleshoot, because the exception thrown inside Win32 dll will not travel further along the stack instead it will simply crash and you will not get the reason. Where else in COM you can catch exception internally and the COMException thrown inside .NET will not crash your entire application.
COM will be little slower in performance, but it will be more organized and good design pattern to develop.

C++ calling C# options

We have native Win32 C++ code and a set of C# assemblies which we wish to call from the C++ code. I summaries our optios as:
Use COM. The C# code would need to be decorated with additional attributes (GUID, COMVisible). The C# assemblies would need to be registered regasm and would then be available to the native C++ code via COM.
Use a C++/CLI (formerly managed C++) wrapper class. A C++ class could be added to the native C++ project. That class would be compiled with /clr. The native C++ code would call the C++/CLI class which would then call the .Net code. No COM involved. The CLR is started by magic as required with marshalling handled by the C++/CLI extenstions.
Host an instance of the CLR in the native C++ code.
I'm going to discount option 3 as I don't see the benefits over option 2 other than we lose the need for a wrapper class. So the question is, what are the pros/cons of option 1 versus option 2?
Thanks in advance.
Option 2 will perform the best, and be the most seamless and maintainable, IMO.
There is really no advantage to option 1 that I've found. Using C++/CLI seems to function much better, work faster, and be much simpler in general.
You also can, btw, just use the C# assembly directly without having a wrapper class. This does require compiling any files that want to use it with /CLR, but it works quite well.
For option 1 your main pro would be not having to write a wrapper class which can get hairy depending on your project.
For option 2 you won't have to modify your managed library to facilitate unmanaged use, which is sometimes not an option.
For me it comes down to where you want to make your code changes.
With option 2 you also have a pretty straightforward way of subsequently convert your whole application to C++/CLI to avoid the managed/unmanaged transitions that you will get. The transitions could be an issue depending on how you use your referenced assemblies i.e. getting a performance hit.
So far I have had only positive experiences with C++/CLI and can recommend going that route.

Categories

Resources