We're looking at writing a .Net-callable wrapper for some legacy C++ libraries using managed C++.
It all looks pretty easy. Is there anything we need to watch out for?
We're looking at writing a .Net-callable wrapper for some legacy C++ libraries using managed C++.
It all looks pretty easy. Is there anything we need to watch out for?
As said by others: 98% of the time it just works, its debuggable, and fast.
What I encountered beyond mentiond so far:
It even worked so well that I started on writing C++/CLI code to run unit tests on C++ code. NUnit/Resharper will happily find and run the unit test in a C++/CLI DLL, that can directly call into your native code at ANY LEVEL, even test your template container classes.
I'll just add to what everyone has already said,
pin_ptr wch = PtrToStringChars(string); (where string is a System::String)
will become your friend.
You can't directly include a non-managed class into a managed class but you can put a pointer to the unmanaged class and new it in your constructor and delete it in your destructor.
I haven't had the problems Timo Geusch mentioned with mixing C++ and C++/CLI code in one DLL. My DLL uses both extensively without problems.
C++/CLI is not difficult (if you know C++ and .NET) and works great.
Just some issues which we encountered:
It is pretty straight-forward and works well. It is a lot easier than PInvoke.
The big thing you need to watch out for is not having any unmanaged members in your managed headers, including private members, method signatures, etc. It is okay to have private members that are pointers to managed types though, just use forward declarations for your classes.
Also, watch out for object lifetime. It is easy to introduce memory leaks since many .NET programmers are not used to cleaning up after themselves. Make sure any wrapper classes that you create are disposable if they contain pointers and make sure you dispose of them in your managed code. The syntax for IDisposable in managed C++ is also weird, but it is in the docs.
Also, remember that you incur a slight hit every time you cross the managed/unmanaged boundary, so try to plan your interface accordingly. If anything gets called repeatedly in loops, it is probably better to move that loop across the boundary so you only cross once. Don't worry too much about this though unless you are talking millions of calls.
This article goes the other way, but it has some useful points.
Use Our ManWrap Library to Get the Best of .NET in Native C++ Code
See also
Managed Code in Visual Studio 2005 and
Deleting Managed Objects, Wrapping a Library, and More
I found it generally quite easy to wrap some existing C++ libraries in C++/CLI and encountered comparatively few pitfalls. The ones I can remember were: