Есть ли способ подключить управляемую функцию в C #, как я бы неуправляемую функцию в C ++? - PullRequest
11 голосов
/ 29 мая 2011

В C ++ я получал бы адрес функции и переписывал первые несколько байтов в jmp своей функции, делал некоторые вещи, восстанавливал исходные байты и вызывал исходную функцию.

Могу ли я сделать что-то подобное в C #?

Ответы [ 3 ]

9 голосов
/ 30 мая 2011

.NET Profiler API - самый близкий «одобренный Microsoft» способ перехвата методов во время выполнения.Как уже упоминалось, это несколько сложно реализовать, и мне неизвестна библиотека, которая бы позволяла это легко реализовать с помощью чисто управляемого кода.

Во время исследования вариантов для этого сам несколько месяцев назад я наткнулся на Инъекция метода CLR - статья с исходным кодом, объясняющая, как перехватывать методы во время выполнения.Я подумал об использовании этого самостоятельно, и даже имел пример работающего проекта, но в конечном итоге пришел к выводу, что мне нужно больше, чем перехват метода, и мне нужно другое решение.Тем не менее, этот подход прямо отвечает на ваш вопрос.

Наконец, в итоге я разработал Afterthought в качестве альтернативы с открытым исходным кодом PostSharp , который работает как пост-компилировать шаг и позволяет модифицировать существующие методы для вызова другого кода или полностью заменить реализации метода.Сейчас я работаю над новым текучим синтаксисом, который я сейчас включу в пример, чтобы предоставить пример, чтобы помочь вам увидеть, как этот подход АОП будет соответствовать вашим потребностям:

Methods
    .Named("Sum")
    .WithParams<int[]>()
    .Before((T instance, ref int[] values)
        => { var s = new Stopwatch(); s.Start(); return s; })
    .After((instance, stopwatch, values)
        => instance.Result = (int)stopwatch.ElapsedMilliseconds);   

В этом случае при внесении поправоксуществующий тип с методом Sum Я представляю код до и после метода для измерения времени выполнения.После запуска Afterthought для исходного скомпилированного класса полученный метод Sum будет вызывать эти лямбда-выражения (компилятор C # просто превращает их в статические методы) до и после тела метода.Я мог бы так же легко назвать Implement и заменить всю реализацию метода.

Я надеюсь, что один из этих подходов удовлетворит ваши потребности.В моем случае я пошел по пути AOP, потому что хотел сделать больше, чем перехват, такой как реализация интерфейсов, добавление новых методов / свойств и т. Д. Я также хотел что-то, что не вводило бы зависимости во время выполнения или проблемы со стабильностью или производительностью всреда выполнения - обработка во время компиляции просто безопаснее и проще для тестирования.

2 голосов
/ 29 мая 2011

Вы хотите подключить во время выполнения или вы хотите исправить двоичный файл?

Чтобы подключить во время выполнения, вы можете использовать API профилирования (относительно сложно): http://msdn.microsoft.com/en-us/magazine/cc188743.aspx

Дляперехватить во время компиляции вы можете использовать переписывающее устройство IL, например, PostSharp.

0 голосов
/ 29 мая 2011

Техника, которую вы ищете, называется AOP - Аспектно-ориентированное программирование.Вы можете найти несколько платформ для C #, если немного поглядите.

Обновление : вы можете найти множество ссылок и информации в этом вопросе: Встроенный AOP в C # - естьэто в пути?

...