When using C++ code in C#, we sometimes need to wrap the C++ code into a DLL (Dynamic Link Library) for several important reasons:
- Interoperability
C# and C++ are fundamentally different languages with distinct runtime environments. C# runs on the .NET Common Language Runtime (CLR), while C++ typically runs as native code
- Compilation and Linking
C++ code needs to be compiled into machine code that can be executed directly by the processor. C#, on the other hand, is compiled into intermediate language (IL) code that runs on the CLR
- Reusability and Maintenance
Wrapping C++ code in a DLL promotes code reuse and easier maintenance
Outline
How to create a cpp DLL
Source code: https://github.com/tuttelikz/notes/tree/main/cpp-dll-dotnet/CustomMath
Create a new DLL project
Open Visual Studio > Create a new project > Set "C++", "Windows" and "Library" filters to find the template > click Next
Give a project name
Set any name to the project > click Create
Create operators.cpp
Project > Add New Item > C++ File (.cpp) > Set name to .cpp
file > Add
Add code to operators.cpp
We defined two simple functions as part of the library
#include "pch.h"
int multiply3(int n)
{
return n * 3;
}
int add5(int n)
{
return n + 5;
}
Create operators.h
Project > Add New Item > Header File (.h) > Set name to .h
file > Add
Add code to operators.h
This code is responsible to export previously defined functions from the DLL
#pragma once
extern "C" __declspec(dllexport) int add5(int n);
extern "C" __declspec(dllexport) int multiply3(int n);
-
extern
means that the entity has external linkage, i.e. is visible outside its translation unit (C or CPP file). -
__declspec(dllexport)
means that the symbol should be exported from a DLL. It is used when compiling the code that goes into the DLL.
Sources:
- https://stackoverflow.com/a/2288355/5151687
- https://learn.microsoft.com/en-us/cpp/build/exporting-cpp-functions-for-use-in-c-language-executables?view=msvc-170
Calling DLL function in dotnet
Source code: https://github.com/tuttelikz/notes/tree/main/cpp-dll-dotnet/ClientApp
Create a console application
Open Visual Studio > Create a new project > Set "C#", "Windows" and "Console" filters to find the template > click Next
Give a project name
Set any name to the project > click Create
Create CustomMathApi.cs
Project > Add Class > Class > Set name to .cs
file > Add
Add code to CustomMathApi.cs
A separate wrapper C# class is created to import DLL functions and interface calls from C#, like an API.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CustomMathAPI
{
public static class CustomMath
{
private const string _dllImportPath = @"C:\Users\saska\source\repos\notes\cpp-dll-dotnet\CustomMath\x64\Debug\CustomMath.dll";
[DllImport(_dllImportPath, CallingConvention = CallingConvention.Cdecl)]
public static extern int add5(int n);
[DllImport(_dllImportPath, CallingConvention = CallingConvention.Cdecl)]
public static extern int multiply3(int n);
}
}
- We should use
System.Runtime.InteropServices
-
_dllImportPath
is used to define a DLL function in managed code
Sources:
Add code to Program.cs
This code calls the imported DLL functions and prints the result
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomMathAPI;
namespace ClientApp
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine($"Calling dll CustomMath.add5(4): {CustomMath.add5(4)}");
Console.WriteLine($"Calling dll CustomMath.multiply3(4): {CustomMath.multiply3(4)}");
Console.ReadLine();
}
}
}
Check the output
Run the code to see the result: Debug > Start Debugging
Note: Solution configuration should be set same as DLL (Configuration > "Debug", Platform > "x64")
Thanks for reading! Stay tuned for more content, and feel free to share your thoughts and feedback! Your reactions help me improve and create even more useful posts 🙂
Alternate URL: https://github.com/tuttelikz/notes/tree/main/cpp-dll-dotnet
Top comments (0)