■ DynamicMethod 클래스를 사용해 객체 주소를 구하는 방법을 보여준다.
▶ SomeClass.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
namespace TestProject { /// <summary> /// 샘플 클래스 /// </summary> public class SampleClass { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 값 - Value /// <summary> /// 값 /// </summary> public int Value { get; set; } #endregion } } |
▶ ReferenceHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
using System; using System.Reflection.Emit; namespace TestProject { /// <summary> /// 참조 헬퍼 /// </summary> public static class ReferenceHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 고정 포인터 구하기 액션 /// </summary> public static readonly Action<object, Action<IntPtr>> GetPinnedPointer; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Static #region 생성자 - ReferenceHelper() /// <summary> /// 생성자 /// </summary> static ReferenceHelper() { DynamicMethod dynamicMethod = new DynamicMethod ( "GetPinnedPointer", typeof(void), new[] { typeof(object), typeof(Action<IntPtr>) }, typeof(ReferenceHelper).Module ); ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.DeclareLocal(typeof(object), true); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Conv_I ); ilGenerator.Emit(OpCodes.Call, typeof(Action<IntPtr>).GetMethod("Invoke")); ilGenerator.Emit(OpCodes.Ret ); GetPinnedPointer = (Action<object, Action<IntPtr>>)dynamicMethod.CreateDelegate(typeof(Action<object, Action<IntPtr>>)); } #endregion } } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using System; using System.Runtime.InteropServices; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static unsafe void Main() { SampleClass source = new SampleClass(); ReferenceHelper.GetPinnedPointer ( source, pointer => { Console.WriteLine(Marshal.ReadIntPtr(pointer)); Console.WriteLine(typeof(SampleClass).TypeHandle.Value); } ); } #endregion } } |