Здравствуйте, Serginio1, Вы писали:
V>>И да, сейчас получить указатель непосредственным образом можно только на статические методы.
V>>Ниже в сырцах можно подсмотреть, как получить указатель на экземплярный метод и как вызывать затем.
S> Нет не надо.
В твоих цитатах не объясняется — почему не надо.
Зато я могу объяснить, почему трюк имеет право на жизнь, по крайней мере в мейнстримовых платформах — из-за соглашений о передаче параметров.
См, к примеру:
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
Т.е., this передаётся как обычный аргумент при вызовах, поэтому, для нестатического метода добавляется первый аргумент для this без лишний приседаний.
S>Кстати вызов из натива можно напрямую через https://docs.microsoft.com/ru-ru/dotnet/core/tutorials/netcore-hosting
Можно, только какая разница, кто хостит дотнет-машинку — утилита dotnet или наше приложение?
На стоимость вызова из дотнета в нейтив и обратно это не влияет.
S>А что касается упрощения вызовов можно через Source Generator нагенерить методов типа
S>static T WrapClassMethod(int i,param1,param2,...)
Можно, но всё-равно вызов managed-функции через новый тип указателя быстрее всего что только может быть — ассемблерный листинг я приводил, тупо кладутся в регистры (согласно соглашению о вызовах) аргументы, в RAX читается содержимое указателя и затем вызывается call RAX. Ничего быстрее не придумаешь.
Итого:
— получение указателя на ф-ию (обычно) не приводит к выделению памяти, как оно есть в случае делегата;
— не приводит к созданию объекта-делегата, где это создание тяжеловесное и помимо выделения памяти;
— вызов происходит эффективнее, чем через делегат;
— тип указателя на ф-ию определяется сигнатурой её параметров, возвращаемого значения и соглашения о вызовах, а не искуственно-введенным типом делегата, где различные типы делегатов с одинаковой сигнатурой, увы, несовместимы.
Ну и, самое главное, это еще один инструмент проектирования.
Декомпозиция делегата-замыкания отдельно на адрес ф-ии и на ссылку на объект позволяет комбинировать в легковесной манере такие сценарии:
— вызов в цикле одного и того же экземплярного метода, поданного в кач-ве параметра, у разных экземпляров;
— вызов нескольких методов, поданных как параметр, у одного экземпляра.
Оба в комбинации друг с другом легковесно заменяют двойные виртуальные вызовы на один вызов по указателю на метод.
Например, есть способ построения конечного автомата на указателях на методы, представляющие состояние.
Т.е., когда автомат ходит по состояниям, он изменяет текущее состояние через запоминание адреса метода, отвечающего за обработку входящих сигналов, и формирующего, как один из результатов своей работы, следующее состояние. Такой способ построения автомата считается одним из самых эффективных, т.к. переход на след.состояние — это просто вызов ф-ии по адресу. Учитывая, что в .Net 6.0 открыли кишки AsyncMethodBuilder и теперь можно писать произвольные свои асинхронные автоматы, я ожидаю рано или поздно появления более эффективных реализаций, чем имеющиеся дефолтные сейчас. Т.е. техника continuations может зацвести в дотнете новыми красками.