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

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.

Related

Managed C++ (C++/CLI) vs C#/VB.NET

I have worked extensively with C#, however, I am starting a project where our client wishes all code to be written in C++ rather than C#. This project will be a mix between managed (.NET 4.0) and native C++. Being that I have always preferred C# to C++ for my .NET needs, I am wondering if there are any important differences I may not be aware of between using C# and managed C++?
Any insight into this is greatly appreciated.
EDIT Looking at Wikipedia for managed C++ code shows that the new specification is C++/CLI, and that "managed C++" is deprecated. Updated the title to reflect this.
C++/CLI is a full fledged .NET language, and just like other .NET languages it works very well in a managed context. Just as working with native calls in C# can be a pain interleaving native C++ and Managed C++ can lead to some issues. With that said, if you are working with a lot native C++ code I would prefer to use C++/CLI over C#. There are quite a few gotchas most of which could be covered by do not write C++/CLI as if your were writing C# nor write it as if you were writing native C++. It is its own thing.
I have worked on several C++/CLI projects and the approach I would take really depends on the exposure of different levels of the application to native C++ code. If the majority of core of the application is native and the integration point between the native and managed code is a little fuzzy then I would use C++/CLI throughout. The benefit of the control in the C++/CLI will outweigh its problems. If you do have clear interaction points that could be adapted or abstracted then I would strongly suggest the creation of a C++/CLI bridging layer with C# above and C++ below. The main reason for this is that tools for C# are just more mature and more ubiquitous than the corresponding tools for C++/CLI. With that said, the project I have been working on has been successful and was not the nightmare the other pointed to.
I would also make sure you understand why the client is headed in this direction. If the idea is that they have a bunch of C++ developers and they want to make it simpler for them to move to write managed code I would posit to the client that learning C# may be less challenging then learning C++/CLI.
If the client believes that C++/CLI is faster that is just incorrect as they all compile down to IL. However, if the client has a lot of existing or ongoing native C++ development then the current path may in fact be best.
I've done a project with C++/CLI and I have to say it was an abomination. Basically it was a WinForms application to manage employees, hockey games, trades between teams, calendars etc, etc...
So you can imagine the number of managed controls I had on my forms: calendars / date time pickers, combo boxes, grids etc.
The worst part was to use only C++ types for my back-end, and use the managed types for the front-end. First off you can't assign a std string to a managed string. You'll need to convert everything. Obviously you'll have to convert it back...
Every time I needed to fill a grid, I serialized my C++ collections to something like a vector<std::string>, retrieve that in my UI library and then looped trough that and made new DataGridRow to add them to the grid. Which obviously can be done in 3 minutes with C# and some Linq to SQL.
I ended up with A+ for that application but lets be honest it absolutely sucked. I just can't imagine how pathetic the others app were for me to get that.
I think it would've been easier if i used List<Customer>^ (managed List of some object) in my C++ instead of always converting everything between vectors of strings. But I needed to keep the C++ clean of managed stuff.
/pissedof
From using all three areas (.NET, C++/CLI and C++) I can say that in everyway I prefer using .NET (through C# or VB.NET). For applications you can use either WinForms or WPF (the latter of which I find far better - especially for applications that look far more user friendly).
A major issue with C++/CLI is that you don't have all the nice language features that you get in .NET. For example, the yield keyword in C# and the use of lambda (I don't think that's supported in C++/CLI - don't hold me to that).
There is, however, one big advantage of C++/CLI. That is that you can create a bridge to allow C# and C++ to communicate. I am currently working on a project whereby a lot of math calculations and algorithms have already been written (over many years) in C++, but the company is wanting to move to a .NET-based user interface. After researching into various solutions, I came to the conclusion that C++/CLI was far better for this. One benefit is that it allowed me to build an API that, for a .NET developer, looked and worked just like a .NET type.
For developing an application's front end, however, I would really not recommend C++/CLI. From a usability point of view (in terms of developer time when using it) it just isn't worth it. One big issue is that VS2010 dropped support for IntelliSense for C++/CLI in order to "improve general IntelliSense" (I think specifically for C++). If you haven't already tried it, I would definitely advise checking out WPF for applications.

Native C++ performance using C# or within 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.

Using COM dll in C#

We have COM dll which was written in C++ and has been used by the apps written in vb 6.0. My company plans write the newer versions of apps in .Net platform.
As far as the performance is concerned, when using a COM dll in a C# project, what should I choose from the 3 options listed below
Just adding the dll as a com reference
Writing a wrapper dll with C++/Cli
Generating a wrapper dll using TlbImp.exe
Or are there any other options?
Thanks.
Writing a wrapper in C++/CLI isn't that likely to be faster, the COM interop marshaller in the CLR is heavily optimized. It auto-generates machine code stubs from the interop library that you create when you add a reference to the COM server. A does a lot more work that's pretty invisible and very hard to do yourself, related to exceptions.
It makes sure that failure HRESULTs are properly converted to managed exceptions and that managed exceptions cannot leak into the COM server code. The "make it fast" resolve you'll have when you do this will make you cut corners like this. Now you've got something that's fast but unreliable. Getting a managed exception in unmanaged code is brutally hard to diagnose, all the context is gone.
Options 1 and 3 are the same thing. Both generate the interop library, the IDE simply runs the equivalent of Tlbimp for you.
The usual guidance applies here. Do the simple thing first, the interop library is incredibly simple. Only contemplate doing the really hard thing when you can actually measure perf problems and have a realistic idea what to do about it. I've never once seen anybody decide that a C++/CLI wrapper was necessary.
Option 2 is more performant, but not much, especially considering the DLL itself is in VB6.
Not sure if option 3 works at all.
I would personally use option 1, but just keep the interop somewhere safe so that I just keep reusing the same interop and not creating it everytime I add the reference.
Another option is to use new dynamic features and late binding (using Activator to create the object) but that is definitely less performant of all.
Since the component is using COM, it will be easiest to add it as a reference and let visual studio build the proxies. This will be very strait forward and transparent to the .net code. It will not be quite as performant, but most likely it will suit your needs. I would do this first, since it is so easy, and then see how it performs.
If the component was not a COM component, and just a standard c++ dll, then the other two method would probably be a better choice.
A call to COM is slow because of the marshalling of the data. With slow I mean, compared to a call where you do not cross a Managed or COM boundary.
If you need to do a lot of small calls to your COM component, in a performance critical piece of your application, you could wrap (and combine) them with C++.
If the number of calls is minimal, or when they are not performance critical (but aren't all calls performance critical?) I would simply add a reference to the COM dll.
Summary Go for the refence to the COM dll, and test the performance. Since you migrate from VB6, you will get an enourmous performance boost already (string handling in .Net is sooooo much faster).

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.

Reverse PInvoke and create a full unmanaged C# program

I know this is a strange question but the idea is simple: I prefer C# syntax rather than C++:
-Setters and getters directly inside a property
-interfaces
-foreach statement
-possibility to declare an implicit cast operator
other small things...
What I really don't know is if is possible to import a c++ dll (expecially std libraries) in C# if I don't use any namespace (even System)
The idea is just to write a program using everything that you will normally use in C++ (nothing from CLR so), even printf for example
Thanks for any answer
No it is not possible to simply import existing C or C++ files into a C# project. They are very different languages and cannot be mixed at the source level.
The way to mix C# and C++/C applications is at the PInvoke or COM Interop level. This works by duplicating the signatures in C# and allowing the C# compiler to determine the binary layout of the native type in order to marshal between the languages.
There's now something close to this
.NET Native compiles C# to native machine code that performs like C++. You will continue to benefit from the productivity and familiarity of the .NET Framework with the great performance of native code.
It's for Windows Store apps only (desktop apps may come in the future):
Desktop apps are a very important part of our strategy. Initially, we are focusing on Windows Store apps with .NET Native. In the longer term we will continue to improve native compilation for all .NET applications.
And
apps will get deployed on end-user devices as fully self-contained natively compiled code (when .NET Native enters production), and will not have a dependency on the .NET Framework on the target device/machine
No; this is not directly possible. In particular, C++ templates are not supported by C#.

Categories

Resources