2013-01-05 33 views
8

Tôi sẵn sàng sử dụng unsafe. Làm thế nào tôi có thể nhận được một lớp địa chỉ bảng ảo và chuyển đổi nó thành một int?Nhận địa chỉ vtable trong C#?

+1

Tại sao bạn muốn làm điều này? –

+3

@DannyChen: "Để giải trí" –

+0

Hãy xem 'OpCodes.Callvirt' thông qua trình tháo rời. http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.callvirt.aspx – Matthew

Trả lời

4

(EDIT: Shoot - quên bạn có cũng để đảm bảo nó không inlined - xem chỉnh sửa)

Bạn không cần phải an toàn, nhưng bạn cần phải thực hiện chắc chắn phương pháp đã được JIT'ed (mà .PrepareMethod không):

caveat: Tôi không hoàn toàn chắc chắn (không có một số nghiên cứu thêm) làm thế nào chính xác những con số này là dài hạn; Tôi biết rằng tại một thời điểm họ sử dụng là chính xác, như tôi đã từng được sử dụng này để thời gian chạy triển khai phương pháp hoán đổi ... shh

using System; 
using System.Runtime.CompilerServices; 
void Main() 
{ 
    long typeHandle = typeof(Foo).TypeHandle.Value.ToInt64(); 
    Console.WriteLine("addressOf(typeof(Foo)): 0x{0:x}", typeHandle); 

    MethodInfo instanceMethod1 = typeof(Foo).GetMethod("InstanceFunc1"); 
    RuntimeHelpers.PrepareMethod(instanceMethod1.MethodHandle); 
    long addressOfInstanceMethod1 = instanceMethod1.MethodHandle.GetFunctionPointer().ToInt64(); 
    Console.WriteLine("foo.InstanceFunc1:  0x{0:x}", addressOfInstanceMethod1); 

    MethodInfo instanceMethod2 = typeof(Foo).GetMethod("InstanceFunc2"); 
    RuntimeHelpers.PrepareMethod(instanceMethod2.MethodHandle); 
    long addressOfInstanceMethod2 = instanceMethod2.MethodHandle.GetFunctionPointer().ToInt64(); 
    Console.WriteLine("foo.InstanceFunc2:  0x{0:x}", addressOfInstanceMethod2); 

    MethodInfo staticMethod = typeof(Foo).GetMethod("StaticFunc"); 
    RuntimeHelpers.PrepareMethod(staticMethod.MethodHandle); 
    long addressOfStaticMethod = staticMethod.MethodHandle.GetFunctionPointer().ToInt64(); 
    Console.WriteLine("Foo.StaticFunc:   0x{0:x}", addressOfStaticMethod); 
} 

public class Foo 
{ 
    [MethodImpl(MethodImplOptions.NoInlining)] 
    public static int StaticFunc() { return 1; } 
    [MethodImpl(MethodImplOptions.NoInlining)] 
    public int InstanceFunc1() { return 1; } 
    [MethodImpl(MethodImplOptions.NoInlining)] 
    public int InstanceFunc2() { return 1; } 
} 
+0

Tại sao nó di chuyển các chức năng xung quanh trong bộ nhớ? Chúng là đối tượng, vì vậy chúng sẽ không chỉ ở một địa chỉ liên tục (thay đổi trên mỗi biên dịch) –

+0

@ColeJohnson Xin lỗi, bỏ lỡ khủng khiếp và không hiệu đính: Tôi muốn nói bố cục của các đối tượng và các tham chiếu khác đã thay đổi từ phiên bản thành phiên bản của CLR; đáng chú ý nhất là giữa 2.0-> 4.0. Tôi sẽ chỉnh sửa. Ngoài ra, chỉnh sửa tốt. :) – JerKimball

+0

Điều này có vẻ rất thú vị;) –

Các vấn đề liên quan