You sure can, and I've done so on both Windows and Mac using .NET Core 3.1, but it will most likely work with .NET Framework as well with minimal modification.
The method I used is called
DllImport and is describe here: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute?view=netframework-4.8#examples
Below is an example from my own C# code.
// This is where you declare the functions from the C file that you want to use. The filename is a relative path to the file containing the `Program`
static extern string say_hello(byte buffer);
static void Main()
var buffer = new byte; // create byte buffer
say_hello(buffer) // call the C function
Console.WriteLine(Encoding.ASCII.GetString(buffer)) // 'hello'
The most important part is to ensure that the C library that you're using is compiled for the platform you're running on.
If you'll be passing large data back to the C# program, you might think about using a library called
cJSON and passing a C struct as JSON to the the
buffer, that you can then deserialize into C# class instances. That's how I did it, and it really keeps the C complexity down since you don't really need to worry about freeing heap space from the C# code.
Please note that I accomplished the above using non-Microsoft tooling for C development (of course I did use .NET Core and CLI for the C# stuff). I don't particularly like Visual Studio and Visual C++ and that is my own bias.