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?

10
  • So, C# to C to C++? Feb 4, 2022 at 4: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. Feb 4, 2022 at 4: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 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 4, 2022 at 6: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, 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 4, 2022 at 7: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. Feb 4, 2022 at 8:31

1 Answer 1

-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.

4
  • 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 4, 2022 at 13:36
  • "prefer command/query". As opposed to...? Passing in handles? Why would I regret C++/CLI?
    – DLT
    Feb 4, 2022 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 8, 2022 at 1: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 8, 2022 at 1:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.