Compose partially implementation both .NET language and IL assembler. An improved implementation of the principles of ILSupport. If you are looking for an inline assembler for CIL/MSIL, here is a realistic solution.
In sample.cs:
namespace IL2C.BasicTypes
{
public class System_Boolean
{
// Refer IL assembly
[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern void ValueTypeTest();
}
}
In sample.il:
.class public IL2C.BasicTypes.System_Boolean
{
.method public static void ValueTypeTest() cil managed
{
.maxstack 2
ldc.i4.s 123
box bool
; ...
ret
}
}
These source code compose into one assembly by ILCompose. Semantically, it is similar to the C# partial class definition, but it does this at the CIL level.
All CIL assemble source code (*.il) are automatically assembled by official dotnet IL assembler ILAsm
.
Only you have to do install the NuGet package ILCompose and ready to use!
Supported target platforms:
- .NET 8, 7, 6, 5
- .NET Core 3.1 to 2.0 (maybe to 1.0)
- .NET Standard 2.1, 2.0 (maybe to 1.0)
- .NET Framework 4.8 to 2.0 (maybe to 1.0)
Supported building platforms:
- dotnet SDK 8, 7, 6, 5, 3.1, 2.2 and 2.1 (on Windows and Linux)
- .NET Framework 4.8 to 4.6.2 on Windows (With dotnet SDK installation)
In short example:
$ dotnet new console
$ dotnet add package ILCompose
[Then write your code both *.cs and *.il ...]
See fully sample code:
You can choose IL assembler between:
- ILAsm.Managed: Defaulted, no need to action.
- CoreCLR ILAsm: Optional, need to set
<ILComposeUsingILAsmManaged>false</ILComposeUsingILAsmManaged>
into<PropertyGroup>
. - Your own
ilasm.exe
: Optional, need to set<ILComposeILAsmToolPath>
and<ILComposeILAsmToolOptions>
.
Because CoreCLR ILAsm package contains many different sub packages included native binary each OS distributions.
And standard dynamic reference script technique has a problem,
could not effect MSBuild script conditions at running dotnet restore
and nuget restore
time except using Visual Studio IDE.
If you are concerned about the stock ILAsm, and in fact ILAsm.Managed fails to compile, you can accept the above problem and use it.
ILSupport is cumbersome because it requires custom build scripts to be incorporated into the your project. However, ILCompose is simply installation the NuGet package and builds everything automatically.
When you install the NuGet package,
the CIL (*.il) file will have the ILComposeTargetIL
build action set as follows:
Basically, it can be used in the same way as ILSupport.
ILSupport is realized using ILDasm and a string substitution technique. While ILCompose is realized using cecil, so the internal implementations are completely different.
Here is where the problem was in ILSupport.
The following C# code with the forwardref
attribute applied cannot apply the additional custom attributes
(they must be written on the IL assembly source code side):
// Refer IL assembly, all additional custom attribute will silently remove by ILSupport.
[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern void ValueTypeTest();
It allows you to apply custom attributes normally, as shown below:
// Refer IL assembly with custom attributes
[Test]
[Description("A value type test.")]
[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern void ValueTypeTest();
When assembling your loose IL source code with implicit referenced assemblies,
ILAsm
will cause these warnings below.
ILAsm.Managed:
Warning -- Reference to undeclared extern assembly 'netstandard', adding.
Warning -- Reference to undeclared extern assembly 'System.Runtime', adding.
Warning -- Reference to undeclared extern assembly 'mscorlib', adding.
CoreCLR ILAsm:
warning : Reference to undeclared extern assembly 'netstandard'. Attempting autodetect
warning : Reference to undeclared extern assembly 'System.Runtime'. Attempting autodetect
warning : Reference to undeclared extern assembly 'mscorlib'. Attempting autodetect
...
See also: dotnet/runtime: ilasm cannot compile against different corlib names
ILCompose has no control these warning on ILAsm
,
but ILCompose will resolve these inconsistent references in the final composite assembly.
Finally, the primary assembly (the original output assembly of the project) is aggregated into referenced assemblies.
For example, mscorlib.dll
for net48
and System.Runtime.dll
for net6.0
.
This feature is disabled <ILComposeAdjustAssemblyReferences>false</ILComposeAdjustAssemblyReferences>
in <PropertyGroup>
element.
<DebugType>
embedded
is not supported.- If no corresponding forwardref method is defined for a CIL method on the source code, that CIL method will not be composed.
This project was created in IL2C, there was a need for IL code management. In IL2C, CIL unit test code was composed into .NET assemblies using ILSupport, but:
- The portion of NUnit that relies on Custom attributes extensions has caused problems on the JetBrains Rider's test explorer, and I wanted to eliminate this. I was thinking of stopping the use of custom attributes extensions.
- In that case, needed to resolve a problem with custom attributes being removed
by the
forwardref
attribute in ILSupport. - To begin with, the ILSupport script was being used with considerable modifications, which caused maintainability problems.
Related: IL2C issue #100: Will upgrade basis environments.
Therefore, I developed this package as a general-purpose package.
Copyright (c) Kouji Matsui (@kozy_kekyo, @kekyo@mastodon.cloud)
License under Apache-v2.