I am writing a cross-platform (OS X and Windows) desktop application in C++11. I intend to use the same C++11 core on both platforms, utilizing native frameworks for the UI (Cocoa and Objective-C on OS X and WPF and C# on Windows) as I believe the best UX experience is a native one.
Currently the application runs as a console app on both platforms. The application performs some CPU-intensive work and provides callbacks for progress reporting and, when complete, instantiates a collection of Items (std::vector<std::unique_ptr<Item>>
) representing the results of the processing.
My goal is for the C++11 library to act as a model for the UI in a manner compatible with the MVC and MVVM patterns.
The UI must:
- Allow the user to choose a file to process (open a file dialog and send the file path to the C++ library)
- Display progress (handle callbacks from the C++ library to update a progress bar)
- Display the results in a WPF form (access the Item class and display information it provides)
I’ve looked at WinRT and it seems there isn’t a lot of information out there for use in desktop applications. I’m also not fond of the idea of creating the UI itself in C++. My goal is to get data in and out of the C++ app and use C# to handle the UI as I believe that’s a more efficient way of working with WPF.
I’m aware of P/Invoke but my understanding is that it only works with a C interface. Creating such an interface around the C++11 seems cumbersome.
I’m also aware of C++/CLI but I’m not sure if that will meet my needs or if it is compatible with C++11.
I took a look at CppSharp but it seems to be a work-in-progress and I doubt I’d know how to work around any issues that may arise.
I have a lot of experience with C++ and a little with C# but I’m not sure if I’m missing better options or which of the above is a sound approach.
16
SWIG can generate C# wrappers for C++ code. I have no experience using it for this, so I don’t know how well it works.
I believe the current release of SWIG (version 2.x) has at least some C++11 support, but you may need to use the development version for full support.
A part of an answer…
Most times in the solution to this problem you will finish up with 3 layers.
- A native C/C++ layer, that can call the Windows API or COM or C++ libraries
- A managed C/C++ layer, that can access the C# object model and framework
- A C# layer, because it’s easier to actually use the .NET Framework and WPF in C#.
P/Invoke refers to the calls between native and managed code, but in this kind of structure they kind of happen inside layer (2). Layer (2) used to be Managed C++ but is now replaced by C++/CLI. Each of the layers can talk to the one next to it easily, but (1) does not easily talk to (3) or vice versa.
You may find a product that just does exactly what you want, but I don’t know one. More likely you will have to write what you need with this kind of layered structure.
I’ve done this 3+ times with 3+ different generations of Managed C/C++, and we have a commercial product built this way (legacy C/C++ <=> ASP.NET/remoting). Each generation the managed layer is different but the overall structure has stayed the same. [edit]
I suggest: write some code, but plan to throw it away. Experimentation is in order.
2
What is a native UI on Windows any more? WPF doesn’t look ‘standard’, winforms and MFC are dead, like Silverlight. It could be said the most native of apps are now HTML, especially if you’re writing Windows8 tiles.
So my suggestion would be to use wxWidgets which uses native controls to render. Your UI will look like a traditional Windows program rather than a “Modern” one, but that’s what you were after isn’t it?
If you do still need to use WPF for the GUI, you can write a C++/CLI interface wrapper that calls your C++ dll, or you could expose your dll as a service and let the WPF make socket (or other RPC) calls into it. If its very chatty, this would not be the best solution, but if it makes few, long-running calls then its ideal. A service would also be the best solution to bind a web front-end to your dll as well, though I’d expose the service as a WWS web service in this case.
4