Skip to content

Instantly share code, notes, and snippets.

@vanbukin
Last active January 1, 2020 16:44
Show Gist options
  • Save vanbukin/c4ebdf8cdc84047428166089c979f27b to your computer and use it in GitHub Desktop.
Save vanbukin/c4ebdf8cdc84047428166089c979f27b to your computer and use it in GitHub Desktop.
Uuid Interop
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
[assembly:IgnoresAccessChecksTo("System.Private.CoreLib")]
namespace Uuid.CoreLib
{
public static class Internal
{
public static unsafe void GetRandomBytes(byte* buffer, int length)
{
Interop.GetRandomBytes(buffer, length);
}
}
}
// ReSharper disable once CheckNamespace
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
public class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
AssemblyName = assemblyName;
}
public string AssemblyName { get; }
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
namespace Uuid.Interop.Compile
{
class Program
{
static void Main(string[] args)
{
var metadataReferences = new[]
{
Assembly.Load(new AssemblyName("System.Runtime")),
Assembly.Load(new AssemblyName("System.Private.CoreLib"))
}
.Select(x => MetadataReference.CreateFromFile(x.Location))
.ToList();
var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithMetadataImportOptions(MetadataImportOptions.Internal)
.WithOptimizationLevel(OptimizationLevel.Release)
.WithAllowUnsafe(true);
var topLevelBinderFlagsProperty = typeof(CSharpCompilationOptions)
.GetProperty("TopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic);
if (topLevelBinderFlagsProperty == null)
throw new Exception("Could not find TopLevelBinderFlags");
topLevelBinderFlagsProperty.SetValue(compilationOptions, (uint) 1 << 22);
var code = GetInteropCode();
var compilation = CSharpCompilation.Create(
"Uuid.CoreLib",
new[]
{
CSharpSyntaxTree.ParseText(code)
},
metadataReferences,
compilationOptions);
using (var ms = new MemoryStream())
{
var compilationResult = compilation.Emit(ms);
if (!compilationResult.Success)
{
throw new Exception(string.Join("\n", compilationResult.Diagnostics));
}
ms.Seek(0, SeekOrigin.Begin);
var assemblyBytes = ms.ToArray();
var output = Path.Combine(Directory.GetCurrentDirectory(), "Uuid.CoreLib.dll");
File.WriteAllBytes(output, assemblyBytes);
Console.WriteLine($"path to dll: {output}");
}
}
private static string GetInteropCode()
{
using var stream =
typeof(Program).Assembly.GetManifestResourceStream("Uuid.Interop.Compile.CoreLibInternal.cs");
if (stream == null)
throw new Exception("Could not find embedded resource that contains interop source code.");
using var reader = new StreamReader(stream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Exe</OutputType>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>
<ItemGroup>
<Compile Remove="CoreLibInternal.cs" />
<EmbeddedResource Include="CoreLibInternal.cs" />
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment