Created
September 24, 2019 22:11
-
-
Save clarvalon/a2f9d27187c029fa677fd6c57c5a23ec to your computer and use it in GitHub Desktop.
FNA Net Core 3 using NativeLibrary (proof of concept - see TODOs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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