How to migrate from C++ COM to C++CLI - c#

I have a C++ DLL that exposes stuff via COM. I want to convert it to C++/CLI that exposes a managed interface. Ideally I just add CLI and convert interfaces one by one. So far I haven't succeeded in anything, so I'm looking for a specific strategy.
More detail:
A long time ago, I created an app using COM to communicate back and forth between C# and C++. I'm sick of COM, and the registration and the hoop jumping needed on the C++ side.
I want to use C++/CLI, and get the whole thing working as managed code with the occasional call from C++/CLI to native libraries I'm using.
Can anyone suggest a gentle migration path, such that I can have both CLI and COM going, and convert things over class by class testing as I go? Or something like that.
To be clear: I currently have native C++ code defining and implementing COM interfaces. I have C# code using COM attributes to export classes. All this stuff gets registered for COM interop, and there are calls in both directions. I hope to switch the C++ to CLI and switch to managed classes in C++ rather than COM classes.
Question updated for Ramhound: Anyway, I'm running into brick walls. Turning on /clr on a C++ dll gives me link errors from other stuff trying to connect to that C++ code. (Unreadable ATL/COM messages of the sort that drive me away from C++)

You may want to read through this, as it provides some different approaches and considerations involved: http://msdn.microsoft.com/en-us/magazine/dd315414.aspx
Here is a simple example of how to use interop in C++/CLI, where you could define a method or two and add more as you go: https://learn.microsoft.com/en-us/archive/blogs/borisj/interop-101-part-1

please follow this
http://msdn.microsoft.com/en-us/magazine/cc163494.aspx
use tlimp to generate a COM unmanaged DLL to a managed DLL
is pretty simple!!!

Related

How to create an inteface either in C# or VB with C++ Logic

My question is what's the best way to create an inteface with C++ code.
Basically so far I have a console project in c++, that works as I expect to, but I now want to make a GUI for it. The choices to me seemed to be:
Make a dll of the c++ project, and then make a C# form which uses the dll to do the logic.
Same as 1 except with VB.
Use QT or something eqvilent and make the inteface in the same project.
I've been trying option 1 for quite sometime. I made the library I believe successfully by making a library project in Visual Studio 2005. I then put it in my c# project but I then had a problem of being able to instantuate my class, but the c# project couldn't see my methods.
The only fix I could find to this was to use the ref keyword. The problem with this was then not being able to mix managed and unmanaged code and trying this on one of the larger classes produced about 250 errors.
Option 2 i had the same problem with.
I'll start option 3 if I have to, I just wondered if I was missing anything fundamental or any suggestions in general?
Cheers for reading.
You absolutely can use C++ code from C#, but if it's unmanaged C++ code, you have to delve into the realm of pinvoke to call your code.
If you're attempting to leverage an existing C++ library from .NET, one of the easiest ways to do this is by using C++/CLI as a wrapper around your unmanaged library. C++/CLI compiles into .NET bytecode, but features lots of automatic unmanaged interop. A phrase that's often floated about when using C++/CLI unmanaged interop is "it just works". It's an accurate phrase.
Once you have a C++/CLI wrapper for your unmanaged code, C# should be able to see everything exposed by your C++/CLI library.

Converting C++ solution to a class library

this might be a simple question, but as I have zero experience in C++ and my boss has given me a C++ solution work with I need to ask this question.
I have a C++ solution that needs to be turned into a .NET class library which can then be used in another .NET solution done in C#.
Is this even possible???
Cheers
You have to wrap all C++ classes that should be visible in .NET in C++/CLI classes.
Read this
There are also some automated tools to do this, but I never used these (I don't really trust them). Depends on how many C++ classes do you have, and how complex they are. Writing the wrappers is mostly straight-forward once you get used to some oddities of C++/CLI.
It depends of the output of the C++ solution. Is it an application (*.exe) or a library (*.dll)?
If it is a library (*.dll) you can use Platform Invoke Tutorial to call its functions out of managed code. A lot of examples of calling Win32 native functions can be found at http://pinvoke.net/.
If your result is an application it could be possible, that it has a COM interface. In that case you could use the COM interop to communicate with your application.
Last but not least you could write with C++/CLI a managed wrapper around your C++ functionality. But this is a lot of work and has many pitfalls.

How to use a C++ library in a C# app?

Thus far I've figured out out I needed to recompile the library as a .dll instead of a .lib, enable /clr and /EHa instead of /EHsc. Now I've got a managed dll which I've added as a reference in my C# project.
Now how do I use it?
I'm prepared to write some wrappers, but I don't know where to begin or how to "see" what functions I've gained access to. I've read a little bit about how the class names and functions might be mangled by the compiler... do I need to go back and add __declspec exports everywhere (if so, how?), or is there an option in VS2010 that says "don't mangle it!"?
The C++ library in question is still under active development, so I'm hoping I can modify the C++ library as little as possible and just recompile it periodically with a few switches, and then expose the new functionality as I need it.
If you are going to compile your C++ (if originally was unmanaged C++) you will need to do much more than just add the /clr switch. In order for C# to use the DLL you will need to create managed classes and other types based on CTS which are compatible with C# (.NET).
See and ref classes.
A good book to read about the subject (IMHO) is this one
You can either expose the functions as C style functions (i.e., no mangling) from your dll or you can expose them as COM objects.
I'd suggest writing a COM wrapper, and using that instead. Have a look at http://msdn.microsoft.com/en-us/library/035x3kbh%28v=VS.80%29.aspx for intro instructions. You'll want to make your object interfaces derived from IDispatch and be automation compatible, which should enable the runtime to consume them without any custom marshaling.
A nice benefit of this approach is you can continue to build your native code as a library, and just make your COM project use it. Also, it's still native code inside the COM object, so there's much less potential for unknown problems (once you get the interface layer working).
That's my suggestion, anyway.
Yes, wrap it in à COM object. I believe ATL is what you meed to do this with the least effort.

MFC Dll with COM Interface

I am pretty new to managed/unmanaged interoperability and COM concepts.
I received a suggestion of using COM Interop, for using my existing MFC code in C#. But the problem for me is, i have a MFC Dll which is not a valid COM component. How can I make this MFC DLLs to have COM-accessible interfaces ready for use in .NET?
From thread Loading MFC DLL in C# Windows Application
To access native code from C# you have a few choices.
Most directly, you can use DllImportAttribute to describe your DLL's entry points in C# terms so that they can be called via P/Invoke. They'll look like static methods to your C# program.
Less directly, you can create a Managed C++ assembly that wraps your DLL in one or more managed objects. The Managed C++ DLL can be accessed from C# via Add Reference (because it is a managed assembly with a .dll extension) and should also be able to access your MFC dll by using #include to include the MFC dll's header file.
A third option would be to turn your dll into a COM object so that your C# program can access it that way.
There is no simple way to make MFC Dll COM accessible. It is necessary to write a lot of COM code manually, making COM wrapper. If you don't have previous COM experience, this may be difficult. The second option from Jacob Seleznev's post looks less painful. C++/CLI wrapper which is internally linked to existing MFC dll, and exposes pure .NET interface to C# client, looks like optimal solution.
If MFC Dll exports C-style interface (API), and not classes, use PInvoke.
From my experience, I concur with #Jacob Seleznev and will add that if your MFC DLL interface contains mainly "simple" parameter and return types, using the DLLImportAttribute is most likely going to be your path of least resistance.
A great reference for marshaling types is to see how it's done against the unmanaged Win32 API. That can be found here:
pinvoke.net
What I've done is find an API call with like types and see how that call is setup on pinvoke.net. I don't use it often anymore, but it was extremely helpful a few years ago.
Hope this helps.
Of the three ways to call native code from managed code (COM Interop, P/Invoke, and IJW or C++/CLI interop), COM Interop is the slowest. And if your existing native code is not in the form of a COM component, then it's also the hardest because that will be step 1.
To use P/Invoke you will need some C-style functions (extern C) that go on and call your existing code. To use IJW or C++/CLI interop you will implement a public ref class (in a file compiled /clr) with methods that go on and call your existing code. It is up to you which you find easier. Once you have the wrapper, from C# you can do the PInvoke with a DllImport attribute on the declaration of the functions, and you then call them as usual. To do the IJW you add a reference to the assembly with the public ref class in it and call the methods on that class as usual.
My recommendation is to ask whether you want some sort of Facade pattern where you're putting some logic in front of the interop - if so, go IJW. Also if you want to control the marshaling, go IJW. If not then go P/Invoke. But either way works.

Sharing objects between C# and C++ code

Is it possible to share references to C# objects between C# and C++ code without massive complexity? Or is this generally considered a bad idea?
The best solution for sharing a C# object between native and managed code is to use COM interop. This allows you to essentially share an interface of an object between managed code and it's equivalent signature in C++.
As for the complexity side of things. The majority of COM interop scenarios are straight forward and really are no more complex than good old COM programming. On the managed side it looks really no different than a normal interface.
Once you introduce multiple threads or start playing around between COM apartments though, things can get a bit tricky.
In my experience, the easiest way to get this working is the following.
Define an interface in C# that you wish to use in C++
Mark the interface with the ComVisible(true) attrbute
Run tlbexp on the assembly which generates a TLB file
Import the TLB into your native project
This will get the interface definition into both of your projects. How to pass that between the projects requires a bit more detail into your architecture.
Another solution I can recommend, from personal experience, is to use a managed C++ interface between the two if the C++ code you want to access is too large or too complex.
For example, I am using the RakNet C++ network library in a C# project. The solutions are to either create a massive wrapper class in C# to access the required C++ functions, create a C++ wrapper around those functions which can than be used as a COM interop or use Managed C++ (Visual C++/CLI).
I chose the latter which allows me to use C++ to access the RakNet library, but the classes created can be used directly in another .NET project as if. So the main logic has been created in those Managed C++ classes, which also allow me to use the .NET framework and some of its wonderful features. In my C# project I simply need to call the Managed C++ library which provides me with all in all 20 functions I need to perform everything.

Categories