2

I am looking for general guidance or any relevant links for a complex project.

We are a small business that sells a construction materials testing software. The client is a Windows application with over 3 million lines of code, written almost entirely in legacy C++98. Business objects are persisted in a SQL database with hand-written serialization/deserialization in C++ without the use of external libraries.

Now we have developed a companion mobile application using Xamarin, soon to be .NET MAUI, which uses .NET standard C#. We have a ASP.NET Core WebAPI that also interacts with the same database as the C++ desktop application. It queries the database and returns json, where the format is documented via OpenAPI.

The challenge now is that there is no abstraction layer that provides an intermediate standard API for interacting with the database: when the user for example saves a complex BO from a dialog in the desktop application, there is no standard way to ensure that the same data is persisted as when we send a POST via the WebAPI, except for duplicating the C++ logic at the WebAPI server endpoint. For GET operations, we also need potentially non-trivial logic to resolve foreign keys etc. Obviously, this approach is not scalable to thousands of BOs.

With all of this preamble, our goal would be to design a common API to enable both the C++ and .NET "worlds" to share the same persistence layer logic.

This is quite challenging, and I am wondering if there are any experiences with how to approach this task.

  • Should the server be ASP.NET Core C# ? (it seems that the options for REST with C++ are quite limited)
  • What technology should be taken to make allow both C++ and C# to access the API? Currently we use pInvoke to call more complex C++ persistence logic. ...

Any pointers, online resources or experiences are would be greatly appreciated! I would be happy to clarify and add more detail if the description is insufficient.

4
  • Have you considered GraphQL as the abstraction layer? Jul 29, 2021 at 12:51
  • Again, buzzword closing goes on here - a good question, but at the end, the OP makes the error of asking for 3rd party resources (which is pretty irrelevant to the main part). And guess what - the "usual suspects" in our community immediately hit the "close" button, without further thinking.
    – Doc Brown
    Jul 30, 2021 at 10:32
  • @DocBrown Thanks for taking the time to respond, but I don't quite understand the gist of your comment. Is there may be some backstory or unwritten rule that I am not aware of, what is the negative connotation you attack to "online resources"? In my head, I was just thinking of maybe some kind of blog resources or similar where developers faced with a similar problem describe how they tackled their project, and the lessons learned.
    – Hottemax
    Jul 30, 2021 at 14:52
  • @Hottemax: the on-topic page says "don't ask for 3rd party resources", and there is also a predefined close-vote option for this. This has lead to the unfortunate situation that some community members here close-vote every question which contains buzzwords like "can one give pointers or online resources", in a pretty braindead fashion, regardless of what the rest of the question contains. More background: my meta question here
    – Doc Brown
    Jul 30, 2021 at 19:57

1 Answer 1

3

One possibility would be to use C++/Cli. This allow a project to contain both native c++ types and managed types. This is available on windows since .Net core 3.1.

The simplest option might be to simply add clr support for some or all of your c++ projects. This should allow them to be referenced from c#. You will need to add managed wrappers around your native types so they can be used from c#, or convert the necessary database access types to managed directly.

I find this easier to use than P/Invoke for more complex usage, since it allow for objects and makes type conversions a bit simpler to understand.

You could also consider more radical changes, like rewriting the database access in c# and make the legacy c++ code use this instead.

A possible downside with this is that c++/cli is not very common, so it may be difficult to find training resources etc. It also does not seem to be a priority for Microsoft, and only Windows support seem to be planned.

4
  • Hi @JonasH, I have heard of C++/CLI. The challenge here would be the part about adding "managed wrappers around the native types" - since it is legacy code all the way down :D, we have hundreds upon hundreds of classes modeling our business domain - how would we go about adding wrappers to this monstrosity? It might be possible, but I have no good intuition where to even start there. Actually,I was thinking if there is any way to utilize builtin Microsoft functionality to convert sql <-> json (docs.microsoft.com/sql/relational-databases/json/…)
    – Hottemax
    Jul 30, 2021 at 14:57
  • 1
    C++/CLI is the de-facto standard technology to combine native C++with the .Net world - I don't know any real competitor. Given the current popularity of both native C++ and .Net, there are probably tons of requirements where programs or libraries of both worlds have to be bridged, in MS software itself as well as in their customer's software. A quick google search for "C++/CLI books" finds some resources, Manning's book ("C++/CLI in action") was ok for my team.
    – Doc Brown
    Jul 30, 2021 at 20:13
  • ... so though C++/CLI isn't the most "sexiest" technology, and not as popular as C# or C++, there is a huge demand from many organizations to keep it alive.
    – Doc Brown
    Jul 31, 2021 at 7:09
  • 1
    @Hottemax, it should be perfectly possible to convert the database schema to corresponding classes. But if you are storing data with custom serialization as binary blobs there is no avoiding some work to wrap or port the (de)serialization. And as with any large task, you need to break it down into smaller parts, preferably parts that can be delivered independently to reduce risk. And if you have large amounts of legacy code the stakeholders should expect slower development. Either do continuous maintenance and updates, or accept the cost when developing new features.
    – JonasH
    Jul 31, 2021 at 16:23

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.