Question

I know the GC can/will move stuff around on the heap. But if you get a pointer to a method, would you ever risk that method being moved?

Second. If you have a pointer to a method is there an unsafe/quick way to invoke it?

Was it helpful?

Solution

But if you get a pointer to a method, would you ever risk that method being moved?

How are you planning on getting the pointer to the method? C# doesn't have such an operation!

Suppose for the sake of argument that you did. The answer to your question is no, methods aren't moved by the GC. Methods aren't deleted, so why would they be moved? You move something in order to compact the hole left behind by a deletion.

But you don't get a pointer to a method in the first place in C#. You get a delegate.

There are ways to get a raw pointer with marshaling code, but what's the point? You can't invoke it.

If you have a pointer to a method is there an unsafe/quick way to invoke it?

But you don't have a pointer to a method in C#, so again, the question is nonsensical.

You invoke a delegate by, well, invoking a delegate.

Now, again, if you somehow managed to get a pointer to a method in C#, is there a way to invoke it that is faster and lighter weight than making a delegate and then invoking that?

No. There is no way in C# to cause the compiler to generate a calli instruction, which is what you need.

The feature is possible; I once played around with a prototype of the features you want. When last I saw the priority list it was very, very low on that list so I would not expect it soon.

OTHER TIPS

I think this question only makes sense in the context of interop with unmanaged code. For example:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, uint threadId);

protected int CbtHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    return Win32.CallNextHookEx(this.cbtHookId, nCode, wParam, lParam);
}

// ...
// keep the delegate reference, avoid "a callback was made on a garbage collected delegate" runtime error
this.cbtHookProc = new Win32.HookProc(CbtHookProc); 

// install the hook
this.cbtHookId = Win32.SetWindowsHookEx(Win32.WH_CBT, this.cbtHookProc,
    IntPtr.Zero, Win32.GetCurrentThreadId());

Note how a thunk for CbtHookProc is created and passed to SetWindowsHookEx. The piece of memory allocated for the think object is fixed for the life-time of this.cbtHookProc, it won't be moved around during heap compaction.

As far as calling unmanaged function pointers, you can call them via:

Use one or both, depending on your needs.

Be sure to correctly set the calling convention, and make sure that you correctly setup the expected environment context for control flow into the function (ie: some functions expect to be invoked on the UI thread, for example, it all depends on the function you are calling into)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top