Interoperability between unmanaged and managed C++ DLL - c++

I currently have an old unmanaged C++ DLL using MFC. This DLL has a bunch of code which is multi-threaded and written back in 2003 using VC6. This code sadly doesn't work anymore.
I've been tasked with finding an alternative way of running this multi-threaded code so that it does function as intended. Someone before me had already rewritten it in C#, and I need to port that C# code over to VC++. I did some research and realized that I could save some time in the porting process by just porting the C# code to VC++ (using the .NET framework). But then I realized that my old MFC DLL cannot run this .NET code.
My idea is to write this multi-threaded code in a VC++ DLL (using the .NET framework) and using some form of interoperability to be able to call the functions from the old DLL to the new DLL.
I have looked into COM interoperability as well as wrapper classes. What is the best way of accomplishing this? Are there any tutorials that could help me with this task? (I've already done some extensive searching and there are a lot of tutorials using unmanaged C++ DLLs to C# DLLs, but not much that pertains to my situtation).
Just so you know, I cannot compile the old DLL with /clr as this DLL is hosted in an old Win32 application as well. Compiling with /clr causes the application to crash, or else this would have already been done.
TO CLARIFY: I'm curious as to why calling functions residing in a C# DLL from an unmanaged C++ DLL through a COM interop seems so simple compared to doing the exact same thing using a managed C++ DLL. I even have a proof-of-concept between C# and C++, but I can't for the life of me begin to understand performing the exact same task with C++. Does there happen to be just a simple tutorial for calling just one simple (let's say 'Add') function from unmanaged C++ to managed C++?

If you have a (managed) DLL, regardless of the language(s) it is written in, you need a process to run it in. If you have a native process that -- for whatever reason -- must not use the CLR, that you cannot directly use a managed DLL (any code that depends on the CLR in-process) from this process directly.
You would need a second helper process that runs the managed DLL and, for example, exposes a COM interface that the native process could call. (out of process COM server)
I have looked into COM interoperability as well as wrapper classes. What is the best way of accomplishing this?
Not sure what you mean with wrapper classes, but an out of process COM server for your managed DLL could do the trick. (Obviously, this is quite some overhand wrt. to managing the proper registration and startup/shutdown of the helper process.)
Breaking the problem up a bit (as far as I understand):
[oldish Win32 app (no! CLR)]
<- normal DLL interface -> [native/MFC DLL (no! CLR)]
<- via COM -> [stuff in a separate executable]
If this is what you are looking for, then this article (just a quick Google hit) may be helpful:
http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx
For COM in general, I think any COM tutorial should cover what you are supposedly trying to do.

Related

Windows GUI and native C++

I'm making a student project called "C++ Game Development". It's a card game with client and server. Client application contains few windows which I've already made with Windows Forms in Visual Studio 2013. For client/server communication I decided to use Internet Communications Engine (ICE). During Build in client's project I had errors in auto-generated code by ICE. I found that ICE doesn't support C++/CLI, only native C++ or C# (that I can't use).
So now I am at a crossroads, whether make the whole client application in native C++ (that means for ex. use MFC which I'm not familiar with) or use both native C++ and C++/CLI (put the work I've done with Windows Forms to CLR Class Library and link to it from native C++ project with entry point) which is also not trivial.
I'm trying to choose the less time-consuming option. I'm asking to help me estimate the complexity of these approaches. I like the second much more but I'm not sure it's the easiest.
It depends how much complexity is already in your GUI. If you have a hundred dialogs/controls then rewriting it in native C++ might be the wrong answer. In this case, making your GUI into a library makes more sense.
However, its probably a better option to keep your GUI as a process and build a proxy library in native C++ that passes the ICE calls onto your server. (so C++/CLI exe calls a function in a new C++ library that makes a ICE call to the server and vice-versa).
If your GUI is small, then rewriting it in a modern (and better supported that C++/CLI) system is the best thing. Qt is probably the ultimate in native GUIs nowadays (but there are alternatives such as MFC, or wxWidgets). Even in these cases, its still probably better to code your networking subsystem as a native library anyway. Then you can change your GUI and try out a load of the GUI stacks as you like, porting your game to Android or iOS with just 1 presentation layer change.
The third alternative is to choose a different comms system. Whilst RPC like ICE are nice, the 'where its at' today is web-based comms via REST services (try an embedded c++ webserver like Mongoose or NxWeb), if you need to push data back to the client, these support WebSockets, so will provide all the functionality you need. And then, you can rewrite your GUI to be HTML based!
So: put your comms in a native C++ library.
C++/CLI can use native C++ code just fine.
Stick the generated code into a "static library project" that builds without /clr. Then list that static library as a dependency of your C++/CLI DLL.
The linker will figure out the rest. The result is called a "mixed-mode assembly".
Note that your comm library may not accept managed types. That's ok, C++/CLI can perfectly well mix unmanaged data model and managed view (UI) classes.

Using MFC in a "managed C++" application

One of our products is a C++ application - using MFC (MDI). (And we skin the application with Codejock.)
I've been asked if we could "port the application to .NET" - so it would be possible to use, e.g., C# libraries and other .NET features. I know there is something called "C++.NET" - or maybe (if I understand it right) it should be called "managed C++" now. But I don't know much about it.
My question: Is this at all possible? Could we run an MFC-application as "managed C++"? (And can an application using Codejock be run as a "managed C++" application?) There is some other threads about this, but I haven't been able to find "a definitive answer"...
I'd be very grateful for some good advice! :-)
As far as I understand, you want to keep your MFC/Codejock GUI and allow the use of .NET libraries from you application's C++ code.
This is indeed possible, but for a complete application that is currently compiled as "native" C++ it is probably not such a good idea to convert all of it to being compiled with C++/CLI. "It Just Works (IJW)" is a nice meme, but it doesn't work always :-)
We have the same situation, namely a C++/MFC/Codejock application that needs to call into .NET assemblies. This works mostly without problems:
We have C++/CLI modules that offer a native C++ DLL interface for the native C++ code to call into and that then route these call on to an assembly written in C#.
We also have C++/CLI assemblies that offer a .NET interface for the C# code and then call back into pure native modules.
It should also be possible to have a single (say, exe) project that is compiled natively and you only enable the /clr switch for selected cpp files that need managed interop. And at the end you link everything together. Since we've never mixed it that way, I can't really say anything about this approach however. What I can say for sure though is that it is possible to compile parts on a module as /clr and parts as native.
I faced a similar problem some years ago, and found that unless for trivial cases converting from un-managed to managed or reverse side was really painfull. I ended leaving the two worlds each in its side, and simply use interop to have the COM - .NET compatibility.
It was not very nice, but a lot cheaper. The conclusion that we should wait a major evolution to consider a full rewriting.

DLL Creation Types

I have a need to create a C++ non-dotnet DLL that will be called and used by a VB.net application. I am trying to determine the type of DLL to create. The DLL will contain some classes, variables, and functions that I will be writing. I understand that there are three types of a DLL that can be created: 1) Regular DLL - Statically Linked to MFC, 2) Regular DLL - Dynamically Linked to MFC, and 3) DLL that uses the Standard Windows Libraries, non-MFC.
My question is, which would be the best to use, one that is linked to the MFC, or one that uses the standard windows libraries? Can someone make a suggestion and explain the differences between MFC and the standard libraries?
Thanks!
Gary
Microsoft Foundation Classes (MFC) are a relatively thin C++ wrapper around the Win32 API, with an emphasis on UI coding. You won't need to statically or dynamically link MFC to your DLL unless you are making use of MFC facilities such as its container classes or trying to display UI written with MFC in your C++ DLL. These are unlikely scenarios.
People have been calling unmanaged code from VB.NET since .NET began. There's a whole wiki available on the subject here at http://www.pinvoke.net/ and there's a useful walkthrough on CodeProject, http://www.codeproject.com/Articles/6243/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part-2 as well. I recommend starting there.
It's a little more complex, but you can also write managed code in C++ by using C++/CLI that can be referenced just like any other managed code assembly instead of using platform invoke. You can use it to create VB-callable managed interfaces that call unmanaged, plain old C++ code. There's an introduction to C++/CLI on MSDN at http://msdn.microsoft.com/en-us/library/ms379617(v=vs.80).aspx and a quick example of using it as a shim for unmanaged C++ in this MSDN Blog entry: http://blogs.msdn.com/b/junfeng/archive/2006/05/20/599434.aspx

Using COM Interop to use a DLL

I have to use a DLL in my project that is a .NET assembly. I have to use C++ for this project. I'm a relative beginner to programming, so my knowledge doesn't extend too far. I was told COM Interop is one way to get the DLL to work in my project (the other being C++/CLI). The problem is I have ZERO idea how to begin, as I've never done anything like this before, and the Microsoft documentation on the matter isn't really helping.
If anyone can even point me in the right direction, that would be much obliged.
Here are some good resources to get you started:
Introduction to COM
COM from Scratch (Covers using COM from C++)
MSDN's section on COM
That being said, you'll also need to make sure that your .NET project is setup to expose the classes via COM. Make sure to turn on Register For COM Interop in your project settings, and flag appropriate types with [ComVisible(true)] (Unless you make the entire assembly ComVisible, in which case you would flag types you don't want to expose with [ComVisible(false)])

Is Winforms accessible from unmanaged C++?

Some classic Windows/C++ applications can't easily be moved to managed C++.net, due to use of external libraries. Is it feasible to use newer GUI libraries like winforms (or even WPF) with such applications, 'dropping in' new controls to replace stale-looking MFC?
Or is it not really worth it, and would take a lot of time?
I've found that C++/CLI is very capable. Are you actually running into problems? It should be able to compile your MFC project directly.
But mixing WinForms and MFC within the same thread could be difficult as they both want to run their own message loop. As Ray Burns has suggested, WPF may be more cooperative with MFC.
Because of IJW it's quite easy to use WinForms or WPF from unmanaged code. More lilkely, though, you'll want to write the new components in managed code and just embed them in your unmanaged application. That means that for all the new stuff you won't have to deal with memory management, etc.
WPF is much more powerful and nicer to use than WinForms, so I would definitely bypass WinForms if you haven't been using it already.
One consideration is you'll want to take advantage of the data binding power of WPF. To do this you'll need to expose your unmanaged data as COM classes or copy the data into managed code. An easy way to do this is to write managed wrapper classes in C++ that access the unmanaged data. Another easy way is to directly access the business object layer (or database) from managed code. It depends on exactly what your current data layer looks like.
A better approach would be to create a new .NET project (C# is your friend) for your UI, and reference your C++ DLLS from there. You're not going to have an easy time mixing managed and unmanaged code in a single project.
See How do I call unmanaged C/C++ code from a C# ASP.NET webpage. It talks about a web page specifically, but the code is identical for a winForms or WPF app.
It's not really worth it, and it would take a huge amount of time.
It's possible to have unmanaged C++ code host the CLR, and to have the managed code run the UI.
But, it's definitely not a trivial task.
An easier approach would be to rewrite the unmanaged code a bit to be invokable via P/Invoke or COM interop, and have a managed app (with winforms) call the unmanaged code.