2014-01-17 2 views
0

Я знаю, что GC может/будет перемещать вещи вокруг на кучу. Но если вы получите указатель на метод, можете ли вы когда-нибудь рискнуть, что этот метод будет перемещен?действительно ли адреса методов перемещаются сборщиком мусора?

Второй. Если у вас есть указатель на метод, существует ли небезопасный/быстрый способ его вызова?

+0

У C# нет указателей. У вас есть ссылки на объекты (или делегаты), и вам не придется беспокоиться о том, чтобы они двигались. Если они это сделают, вы никогда не узнаете об этом. – Steve

+0

Сборщик мусора будет уплотнять кучу. Однако, когда он уплотняет кучу, он обрабатывает обновление адресов памяти. –

+0

@Steve ... У C# есть указатели, чтобы быть точными [MSDN] (http://msdn.microsoft.com/en-us/library/t2yzs44b.aspx) – Jim

ответ

2

Но если вы указали на метод, можете ли вы когда-нибудь рискнуть переместить этот метод?

Как вы планируете получать указатель на метод? C# не имеет такой операции!

Предположим ради аргумента, который вы сделали. Ответ на ваш вопрос - нет, методы не перемещаются GC. Методы не удаляются, так почему бы это так? переехал? Вы перемещаете что-то, чтобы сжать отверстие, оставшееся после удаления.

Но вы не получаете указателя на метод, в первую очередь на C#. Вы получаете делегата.

Есть способы получить необработанный указатель с кодом маршалинга, но в чем смысл? Вы не можете вызвать его.

Если у вас есть указатель на метод, существует ли небезопасный/быстрый способ его вызова?

Но вы не есть указатель на метод в C#, так что опять же, вопрос бессмыслен.

Вы вызываете делегата, вызывая делегат.

Теперь, если вам каким-то образом удалось получить указатель на метод на C#, есть ли способ вызвать его, который быстрее и легче, чем сделать делегат, а затем вызвать это?

No.В C# нет способа заставить компилятор генерировать команду calli, которая вам нужна.

Характеристика Значение возможно; Я когда-то играл с прототипом функций, которые вы хотите. Когда в последний раз я видел список приоритетов, он был очень-очень низким в этом списке, поэтому я не ожидал этого в ближайшее время.

+0

То, что меня интересует. Спасибо! .ps. Может ли F # или Reflection.Emit сделать что-нибудь подобное? –

+1

@AustinHarris: если вы хотите использовать Reflection.Emit для генерации инструкции calli, вы идете прямо вперед и делаете это, но я бы предложил вам, что это, вероятно, больше работы, чем просто создание делегата. Вы должны задать свой вопрос F # эксперту F #. Если только есть веб-сайт, полный экспертов по программированию ... –

+0

Методы иногда могут быть удалены GC: вам нужна сборная сборка (http://msdn.microsoft.com/en-us/library/dd554932 (v = vs.110) .aspx), который, если на нем больше нет ссылок, может быть сбор. Это включает удаление содержащихся методов и их JIT-кода. Это может также повлиять на экземпляры общих методов, которые определены в обычной сборке, но используют тип из сборной сборки. – CodesInChaos

1

Я думаю, что этот вопрос имеет смысл только в контексте взаимодействия с неуправляемым кодом. Например:

[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()); 

Обратите внимание, как создается для CbtHookProc преобразователь и передается SetWindowsHookEx. Часть памяти, выделенная для объекта мысли, фиксируется на время жизни this.cbtHookProc, она не будет перемещаться во время уплотнения кучи.

1

Насколько вызова неуправляемых указателей на функции, вы можете вызвать их с помощью:

Используйте один или оба, в зависимости от ваших потребностей.

Обязательно правильно настройте соглашение о вызове и убедитесь, что вы правильно настроили ожидаемый контекст среды для потока управления в функцию (т. Е. Некоторые функции, ожидающие вызова в потоке пользовательского интерфейса, например, все зависит от о функции, в которую вы звоните)

Смежные вопросы