Sometimes, when I work on hardware-related projects, I see that some tasks are better to implement in C++ than in C#. The reasons are performance-, compatibility-, and culturally related. On the other hand, some functionality, such as web services or database communication, is more efficient to implement in C#. And I got curious: how easy or difficult is it to integrate the benefits of both technologies into a single solution? And, is it possible to debug the control flow transparently through the border between them, as if it were one homogeneous piece of code?
This project is the result of my series of experiments in this direction. Also, it can serve as a boilerplate for developing a native C++ DLL and a C# client EXE in a single Visual Studio solution.
The scope of the experiment is modeling two projects, working together:
- a very abstract device driver (NativeDeviceLib.dll)
- a simple console client application (ManagedClient.exe)
The article describes technical requirements and restrictions of the project, including:
- Application Binary Interface
- Exceptions processing policy
- Function wrapping at the managed side
The development was performed in Microsoft Visual Studio 2026.
Visual Studio should contain the following tools:
- Desktop development with C++
- .NET desktop development
That's it. The solution was developed and tested on macOS running on a Silicon M3 processor under Parallels virtualization environment with Windows 11 Pro. Most likely, the target machine can vary across project configurations, depending on users' hardware.
At Stage 1, the initial solution creation process is described. The solution contains two projects:
- The simplest C++ library with one function that accepts two parameters and returns the sum of them to the client.
- The simplest C# console app which connects to the library, calls the function, and prints the result to the console.
At Stage 2, we emulate real (imaginary) device driver behavior:
- The C++ library exposes two functions to emulate some "measurement" process with different durations.
- The C# client calls these two functions in different tasks to have them working simultaneously, waits until both of them return those results, and prints the results to the console.
- Microsoft: Extern (C++)
- Microsoft: Platform Invoke (P/Invoke)
- Microsoft: Use SIMD-accelerated numeric types