Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mattwarren/ff7e6bb65c1bc2df06ea to your computer and use it in GitHub Desktop.
Save mattwarren/ff7e6bb65c1bc2df06ea to your computer and use it in GitHub Desktop.
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication3.Test
{
static class EntityPtr
{
private static readonly IEntityPtr converter = CreateConverter();
private static IEntityPtr CreateConverter()
{
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("dynamic"), AssemblyBuilderAccess.Run);
var type = assembly.DefineDynamicModule("dynamic_module").DefineType("dynamic_type");
type.AddInterfaceImplementation(typeof(IEntityPtr));
CreateToPointerMethod(type);
CreateToPointerWithOffsetMethod(type);
CreateToObjectMethod(type);
var t = type.CreateType();
return Activator.CreateInstance(t) as IEntityPtr;
}
public static IntPtr ToPointerWithOffset<T>(T obj)
{
return converter.ToPointerWithOffset(obj);
}
public static IntPtr ToPointer<T>(T obj)
{
return converter.ToPointer(obj);
}
public static T ToInstance<T>(IntPtr pointer)
{
return converter.ToInstance<T>(pointer);
}
private static void CreateToPointerWithOffsetMethod(TypeBuilder type)
{
var methodBuilder = type.DefineMethod("ToPointerWithOffset", MethodAttributes.Public | MethodAttributes.Virtual);
var genericParams = methodBuilder.DefineGenericParameters("T")[0];
methodBuilder.SetParameters(genericParams);
methodBuilder.SetReturnType(typeof(IntPtr));
var ilEmit = methodBuilder.GetILGenerator();
ilEmit.Emit(OpCodes.Ldarg_0);
ilEmit.Emit(OpCodes.Ret);
}
private static void CreateToPointerMethod(TypeBuilder tb)
{
var methodBuilder = tb.DefineMethod("ToPointer", MethodAttributes.Public | MethodAttributes.Virtual);
var genericParams = methodBuilder.DefineGenericParameters("T")[0];
methodBuilder.SetParameters(genericParams);
methodBuilder.SetReturnType(typeof(IntPtr));
var ilEmit = methodBuilder.GetILGenerator();
ilEmit.Emit(OpCodes.Ldarg_0);
ilEmit.Emit(OpCodes.Conv_I4);
ilEmit.Emit(OpCodes.Ldc_I4, 4);
ilEmit.Emit(OpCodes.Sub);
ilEmit.Emit(OpCodes.Conv_I);
ilEmit.Emit(OpCodes.Ret);
}
private static void CreateToObjectMethod(TypeBuilder tb)
{
var methodBuilder = tb.DefineMethod("ToInstance", MethodAttributes.Public | MethodAttributes.Virtual);
var genericParams = methodBuilder.DefineGenericParameters("T")[0];
methodBuilder.SetParameters(typeof(IntPtr));
methodBuilder.SetReturnType(genericParams);
var ilEmit = methodBuilder.GetILGenerator();
ilEmit.Emit(OpCodes.Ldarg_0);
ilEmit.Emit(OpCodes.Conv_I4);
ilEmit.Emit(OpCodes.Ldc_I4, 4);
ilEmit.Emit(OpCodes.Add);
ilEmit.Emit(OpCodes.Conv_I);
ilEmit.Emit(OpCodes.Ret);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment