My application is unmanaged. Where do I start introducing managed code?

402 views Asked by At

My whole application (which is rather big, with a 20MB executable) is written in unmanaged C++. Because I can clearly see the advantages in using managed code, I want to start introducing managed code in my application, but where do I start?

Can I easily start to use C++/CLI and link it with the rest of my application? (although the C++/CLI syntax seems rather 'exotic').

Or is it better to move to C#, but what is the best way to 'link' this together with my unmanaged C++ code?

Does it make sense to compile all my C++ code with the /clr option? Will this work?

Do I have to worry about marshalling? Does this give an overhead or can I switch between managed and unmanaged without a performance penalty (just as I did 20 years ago when mixing fortran and C). Performance is really important in my application since it is a scientific application that sometimes processes several Gigabytes of memory.

Or does it only make sense to redesign the user interface, and only write this in C#, and keep the rest of my application (calculation logic, business logic, database interface, ...) in unmanaged C++?

Since my application sometimes needs to handle several Gigabytes of memory, I have a 64-bit variant. Is it easy to have 64-bit managed code? Woudl the garbage collector be still efficient if that much memory is used?

Simply state: where do I start?

Patrick

3

There are 3 answers

0
Patrick On BEST ANSWER

For the moment, consider this question closed.

I realized that the answer is not mixing C++ and C#, but getting the architecture right in the first place.

If the architecture is correct, and separated where it needs to be separated, than changing parts of the application by other modules (external, other language, ...) should be easier.

Regarding the performance problems during marshalling, we will have to wait until .Net has further matured.

0
martinr On

Profile the app, decide at what integration points you can snap off the C# line of logic and break into C++ and vice versa. Arrange these into a plan to have a Facade design pattern move through the system gradually replacing C++ with C#. Of key concern is the CPU and memory cost when deciding to switch languages at each candidate Facade / interface.

You will want to be able to incorporate edits so you might be best off with one source code set and source code repository for the original C++ code and another set and repository for the facade plus the C#.

Then as enhancements/maintenance work comes in the in-tray you apply it to both code bases, and you try to make sure the facade moves through the system starting with the code least likely to change in enhancements or maintenance to minimise doubling of changes work.

Also ideally structure your work so you can rollback the facade to go back to 100% C++ at the drop of a hat if you hit a snag.

To test whether a couple of particularly inscrutable C++ modules can be separated into a C++ piece and a C# piece, run them in two different Win32 C++ processes communicating using a pipe or a socket. That way you'll get a better idea of whether there are problems with memory management or performance that need fixing before you can split the call chain at that point.

0
NotDan On

We do exactly what you described in a mission critical application that is used by thousands of users. Basically, we kept the existing application as is, so the executable is still a 100% unmanaged executable (not C++/CLI). We then put all of our new C# code in .NET dlls which consists of business objects, user controls and gui code, etc....

Basically, all new code is written in C#. We have 1 dll that is C++/CLI that is just glue. This lets us easily interop between the managed and unmanaged code, without having to make the existing C++ code clr. This limits the amount of C++/CLI code we have to write. The native code talks to the mixed mode code, which can talk to the managed code. The mixed mode dll can hook events on the C# classes so the C# code can just fire the event to communicate to the C++/CLI (which can talk to the native code).

We can also host .NET UserControls in an existing C++ app (WinForms is just a wrapper around the WINAPI anyway, so it works pretty well).

This works very well and lets you keep your existing code without having to rewrite the entire GUI in C#.