Skip to content

Commit 0e3d75c

Browse files
committed
Enable way to load interface without generic
1 parent f564f46 commit 0e3d75c

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

src/FRC-Utilities/FRC-Utilities.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<PropertyGroup>
2828
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
2929
<WarningsAsErrors />
30-
<Version>3.0.4</Version>
30+
<Version>3.0.5</Version>
3131
</PropertyGroup>
3232

3333
<ItemGroup>

src/FRC-Utilities/ILGeneration/InterfaceGenerator.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace FRC.ILGeneration
1010
{
11-
internal class InterfaceGenerator<T> where T : class
11+
internal class InterfaceGenerator
1212
{
1313
private readonly IFunctionPointerLoader functionPointerLoader;
1414
private readonly IILGenerator ilGenerator;
@@ -18,15 +18,20 @@ public InterfaceGenerator(IFunctionPointerLoader functionPointerLoader, IILGener
1818
this.functionPointerLoader = functionPointerLoader;
1919
this.ilGenerator = ilGenerator;
2020
}
21+
22+
public T? GenerateImplementation<T>() where T : class
23+
{
24+
return (T?)GenerateImplementation(typeof(T));
25+
}
2126

22-
public T? GenerateImplementation()
27+
public object? GenerateImplementation(Type t)
2328
{
24-
AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(typeof(T).Name + "Asm"), AssemblyBuilderAccess.Run);
25-
ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule(typeof(T).Name + "Module");
26-
TypeBuilder typeBuilder = moduleBuilder.DefineType("Default" + typeof(T).Name);
27-
typeBuilder.AddInterfaceImplementation(typeof(T));
29+
AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(t.Name + "Asm"), AssemblyBuilderAccess.Run);
30+
ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule(t.Name + "Module");
31+
TypeBuilder typeBuilder = moduleBuilder.DefineType("Default" + t.Name);
32+
typeBuilder.AddInterfaceImplementation(t);
2833

29-
var methods = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance);
34+
var methods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance);
3035

3136
foreach (var method in methods)
3237
{
@@ -43,7 +48,7 @@ public InterfaceGenerator(IFunctionPointerLoader functionPointerLoader, IILGener
4348

4449
var typeInfo = typeBuilder.CreateTypeInfo();
4550

46-
return (T?)typeInfo?.GetConstructor(new Type[0]).Invoke(null);
51+
return typeInfo?.GetConstructor(new Type[0]).Invoke(null);
4752
}
4853
}
4954
}

src/FRC-Utilities/NativeLibraryUtilities/NativeLibraryLoader.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,26 @@ public void LoadNativeLibraryFromReflectedAssembly(string assemblyName, bool loc
342342
}
343343

344344
var ilGenerator = new CalliILGenerator();
345-
var interfaceGenerator = new InterfaceGenerator<T>(LibraryLoader, ilGenerator);
346-
return interfaceGenerator.GenerateImplementation();
345+
var interfaceGenerator = new InterfaceGenerator(LibraryLoader, ilGenerator);
346+
return interfaceGenerator.GenerateImplementation<T>();
347+
}
348+
349+
/// <summary>
350+
/// Load a native interface
351+
/// </summary>
352+
/// <returns></returns>
353+
public object? LoadNativeInterface(Type t) {
354+
if (!t.IsInterface) {
355+
throw new InvalidOperationException($"{t.Name} must be an interface");
356+
}
357+
358+
if (LibraryLoader == null) {
359+
throw new InvalidOperationException("A native library is not already loaded");
360+
}
361+
362+
var ilGenerator = new CalliILGenerator();
363+
var interfaceGenerator = new InterfaceGenerator(LibraryLoader, ilGenerator);
364+
return interfaceGenerator.GenerateImplementation(t);
347365
}
348366

349367
private void ExtractNativeLibrary(string resourceLocation, string extractLocation, Assembly asm)

test/FRC-Utilities.Test/ILGeneration/InterfaceGeneratorTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ public void TestInterfaceGeneration1Func()
4141
});
4242

4343
var ilGenerator = new CalliILGenerator();
44-
InterfaceGenerator<I1Func> iGenerator = new InterfaceGenerator<I1Func>(fpLoader, ilGenerator);
45-
var impl = iGenerator.GenerateImplementation();
44+
InterfaceGenerator iGenerator = new InterfaceGenerator(fpLoader, ilGenerator);
45+
var impl = iGenerator.GenerateImplementation<I1Func>();
4646
Assert.NotNull(impl);
4747
int x = 5;
4848
byte r = impl!.FirstFunc(&x);

0 commit comments

Comments
 (0)