2

I have inherited a large C++ codebase implementing various Windows desktop applications, services and libraries using Windows MFC. There are no automated tests. We need to decouple the UI and retain a large part of the domain logic written in C++. My understanding is I can implement high-level use cases in C++ and expose these use cases as functions in a C interface. This interface would take or return structs as payloads, much like a REST API would accept or return JSON.

This design would then allow me to call into the legacy code using a high-level API with a more Ui-friendly language like C# or Javascript. It would provide a clean API to introduce automated tests and would also allow me to migrate the logic and services to the web if required.

Is this approach in line with modern C++ software architecture? Is a C interface the best choice in this scenario? What risks should I be aware of?

DLT
  • 91
  • 5
  • So, C# to C to C++? – Greg Burghardt Feb 04 '22 at 04:35
  • 1
    I feel like you should be able to refactor the c++ code into it's own DLL and then `[DLLImport("TheCPPLib.dll")]` so you can directly call the c++ code from c#. Shouldn't be a need for a C wrapper, right? I haven't tried this, so I'm not sure. – Greg Burghardt Feb 04 '22 at 04:45
  • To clarify, I'm not talking about writing a lot of C code, just C++ I can expose as a simple interface for ABI stability as noted in question https://softwareengineering.stackexchange.com/a/281884/339664. I simply expose an API in C-style with argument types consisting of POD (plain old data). Since it is simple it can provide a future proof API if we choose a different language to bind with and without dealing with memory management, pointers, etc. Is there more or less effort and risk in writing an API that can be used with DLLImport instead? – DLT Feb 04 '22 at 06:27
  • 1
    For encapsulating a large C++ code base and make it accessible by C# on Windows, forget about a C interface, that's not effective. Instead, use [C++/CLI](https://en.wikipedia.org/wiki/C%2B%2B/CLI), that's still the best tool for this task. At my job, we are using this for more than a decade extensively, works pretty well. – Doc Brown Feb 04 '22 at 07:00
  • @DocBrown Except any new .Net development will preferably be in .Net Core (just .Net going forward), while C++/CLI is only supported in .Net Framework. – Sebastian Redl Feb 04 '22 at 08:31
  • @SebastianRedl: C++/CLI support for .Net Core 3.1 is available [since beginning of 2020](https://devblogs.microsoft.com/cppblog/porting-a-c-cli-project-to-net-core/), Windows-only, not cross-platform. – Doc Brown Feb 04 '22 at 11:30
  • @DocBrown Interesting, thanks for that. – Sebastian Redl Feb 04 '22 at 11:52
  • @DocBrown why is a C interface with plain data structures not effective, aren't Windows, Linux, etc API like this? What advantage does C++/CLI offer over a C interface? – DLT Feb 04 '22 at 19:26
  • "I have inherited a large **C++** codebase" - your words. And ... "a more Ui-friendly language like C#". This is your scenario. That's exactly what C++/CLI was designed for. – Doc Brown Feb 04 '22 at 22:01
  • ... but why not simply try it out for yourself? Try to wrap one of your existing C++ classes (not just an isolated function call) with a C interface and use P/Invoke to get access to this wrapper by C#. Then try the same using C++/CLI. – Doc Brown Feb 04 '22 at 22:08

1 Answers1

-3

Yes, do it. This is a surprisingly common problem, and I just finished doing one.

The choice of a C API is a good one, and designing this is really the only hard part. Take it seriously! Just a few thoughts:

  • simple data types: ints, floats, structs (but no pointers)
  • a consistent strategy for variable sized items: strings and arrays
  • prefer command/query
  • be very consistent in naming and usage
  • make sure it's easy and natural to call in C# and Python (then the rest are easy)
  • prefer unit tests in C#
  • probably need 64-bit (if it wasn't already)

Avoid C++/CLI -- it's a quick fix, but you will regret it over time.

david.pfx
  • 8,105
  • 2
  • 21
  • 44
  • C++/CLI is not a quick fix. Having several years of experience with that technology, I know first hand that your last sentence is simply biased nonsense. – Doc Brown Feb 04 '22 at 13:36
  • "prefer command/query". As opposed to...? Passing in handles? Why would I regret C++/CLI? – DLT Feb 04 '22 at 21:54
  • @DocBrown: C++/CLI is superb technology as long as you are totally committed to a Microsoft environment. Not so great if you later need Linux, mono, Unity, etc. – david.pfx May 08 '22 at 01:38
  • @DLT: CQS rather than API calls that both change state and return a value (like much of Windows). Use handles (rather than than pointers) as a choice in how to manage state. This is a topic for a book, not a brief comment. – david.pfx May 08 '22 at 01:44