Skip to content

Instantly share code, notes, and snippets.

@clarvalon
Created September 24, 2019 22:11
Show Gist options
  • Save clarvalon/a2f9d27187c029fa677fd6c57c5a23ec to your computer and use it in GitHub Desktop.
Save clarvalon/a2f9d27187c029fa677fd6c57c5a23ec to your computer and use it in GitHub Desktop.
FNA Net Core 3 using NativeLibrary (proof of concept - see TODOs)
// in Program.cs
// Get FNA Assembly
var fnaAssembly = Assembly.GetAssembly(typeof(Microsoft.Xna.Framework.Graphics.ColorWriteChannels));
// Register mechanism for determining native libraries based on NativeLibrary instead of DllImport
DllMap.Register(fnaAssembly);
// in DllMap.cs
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Xml.Linq;
public static class DllMap
{
// Register a call-back for native library resolution.
public static void Register(Assembly assembly)
{
NativeLibrary.SetDllImportResolver(assembly, MapAndLoad);
}
// The callback: which loads the mapped libray in place of the original
private static IntPtr MapAndLoad(string libraryName, Assembly assembly, DllImportSearchPath? dllImportSearchPath)
{
string mappedName = null;
mappedName = MapLibraryName(assembly.Location, libraryName, out mappedName) ? mappedName : libraryName;
return NativeLibrary.Load(mappedName, assembly, dllImportSearchPath);
}
// Parse the assembly.xml file, and map the old name to the new name of a library.
private static bool MapLibraryName(string assemblyLocation, string originalLibName, out string mappedLibName)
{
// TODO: Cache xml results to prevent costly loads?
// TODO: How to determine "os" at runtime? (i.e. before SDL2 loaded). How does Mono do this? Currently hardcoded
// TODO: How to determine "cpu" at runtime? (e.g. "armv8"). How does Mono do this? Currently not used
// TODO: Remove Console.Writeline
string xmlPath = Path.Combine(Path.GetDirectoryName(assemblyLocation),
Path.GetFileNameWithoutExtension(assemblyLocation) + ".dll.config");
mappedLibName = null;
if (!File.Exists(xmlPath))
{
Console.WriteLine($"=== Cannot find XML");
return false;
}
XElement root = XElement.Load(xmlPath);
var map =
(from el in root.Elements("dllmap")
where (string)el.Attribute("dll") == originalLibName && el.Attribute("os").ToString().IndexOf("linux") >= 0
select el).SingleOrDefault();
if (map != null)
mappedLibName = map.Attribute("target").Value;
Console.WriteLine($"=== Original={originalLibName}, Mapped={mappedLibName}");
return (mappedLibName != null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment