How can I create a DLL for external referencing in .NET?

I'm trying to create a DLL with a simple .NET Core Class Library project. I'd like to be able to use the exposed methods by externally referencing the DLL file.

For example, my simple Class Library project consists of a single method that prints "test".

public class TestDLL
{
    public static void PrintTest()
    {
        Console.WriteLine("test");
    }
}

I'm calling the eventual DLL by referencing it with the DLLImport attribute.

public class Program
{
    public static void Main(string[] args)
    {
        PrintTest();
    }

    [DllImport(@"C:\dev\TestDLL\bin\x64\Debug\netcoreapp3.1\test.dll")]
    public static extern void PrintTest();
}

After compilation, I disassemble the DLL file and manually add the .export descriptor to the PrintTest method in order to expose it. Shown below is a snippet of the disassembled IL file.

.method public hidebysig static void  PrintTest() cil managed
{
  // Code size       13 (0xd)
  .export [1]          // manually inserted descriptor
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "test"
  IL_0006:  call       void [System.Console]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method TestDLL::PrintTest

Finally, I assemble the file into a DLL and call it. Although the file is successfully referenced after inserting the .export descriptor, I get an exception.

Unhandled exception. System.Runtime.InteropServices.SEHException (0x80004005): 
External component has thrown an exception.
  at ConsoleApp.Program.PrintTest()
  at ConsoleApp.Program.Main(String[] args) in 
  C:\dev\test\ConsoleApp\Program.cs:line 11
                                
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or
assembly
  'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
  or one of its dependencies. The system cannot find the file specified.

I tried placing the System.Runtime.dll file in the same folder as the DLL I'm calling, but this didn't help either. What am I missing?


Solution 1:

As suggested by Hans Passant, using DllExport did the trick.

This package relies on inserting the same .export descriptor into the IL files of the targeted project to expose certain methods once the DLL is created. However, this package also takes care of a host of other necessary configuration properties for the targeted .csproj files. As such, simply adding the .export descriptor is not enough when it comes to using .NET and Visual Studio.

It is also important to mention that getting this to work required me to switch from using .NET Core to .NET Standard 2.0 for my Class Library project as I could not get it to work (out of the box) with neither .NET Core nor .NET 6.0.