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.