none
Указатели на функцию, C# RRS feed

  • Вопрос

  • Доброго времени суток. Прошу подсказки в создании указателя на функцию. Именно что указателя, а не делегата.

     

    В общем примерно так: есть функция:

    static double myFunc(double x, double y)
    {
         //тут тело
    }
    
    static void Main()
    {
         //а вот тут надо вызвать функцию myFunc, используя указатель на неё
    }
    

    Очень прошу помощи. Поиск на сторонних ресурчах ничего конкретного не дал. Указатель нужен потому, что так сказано в задании.


    MSDN AA User
    22 октября 2011 г. 22:57

Ответы

  • если функцию надо вызвать из неуправляемого кода, то
    см. Marshal.GetFunctionPointerForDelegate
    • Помечено в качестве ответа Abolmasov Dmitry 24 октября 2011 г. 8:38
    22 октября 2011 г. 23:44
  • По-моему, в C# невозможно получить небезопасный указатель на функцию. Для вызовов таких функций из неуправляемого кода всегда создаётся управляемая обёртка.

    Думал, думал, вот до чего додумался:

    using System;
    using System.Runtime.InteropServices;
    
    class Program
    {
        static double myFunc(double x, double y)
        {
            return x + y;
        }
    
        delegate double MyDel(double x, double y);
    
        static void Main(string[] args)
        {
            unsafe
            {
                MyDel del = new MyDel(myFunc);
                
                IntPtr ptr = Marshal.GetFunctionPointerForDelegate(del);
    
                // Получили указатель на ту самую функцию
                void* p = ptr.ToPointer();
    
                var d = (MyDel)Marshal.GetDelegateForFunctionPointer((IntPtr)p, typeof(MyDel));
    
                Console.WriteLine(d(2, 3));
            }
        }
    }
    


    В этом примере сначала из делегата получаем указатель на функцию, а потом из этого указателя опять получаем делегат, и только так можно вызвать исходный метод.

    Ничего лучше я придумать не смог.

    • Помечено в качестве ответа asdfxcbneftyherwe 23 октября 2011 г. 8:02
    23 октября 2011 г. 2:40

Все ответы

  • > надо вызвать функцию myFunc, используя указатель на неё

    var fn = new Func<double, double, double>(myFunc);
    var res = fn(1,1);
    


    22 октября 2011 г. 23:29
  • или так

    delegate double Dlg(double x, double y);
    ...
    var fn = new Dlg(myFunc);
    var res = fn(1,1);
    

    22 октября 2011 г. 23:31
  • если функцию надо вызвать из неуправляемого кода, то
    см. Marshal.GetFunctionPointerForDelegate
    • Помечено в качестве ответа Abolmasov Dmitry 24 октября 2011 г. 8:38
    22 октября 2011 г. 23:44
  • Возможно я неверно выразился, но я имел в виду те самые указатели, указывающие на конкретный участок памяти. Те которые:

    int* a;
    int b = 10;
    *a = &b;
    

    Вот мне таким же образом нужно получить адрес функции, и обратиться к ней через указатель.


    MSDN AA User
    22 октября 2011 г. 23:44
  • По-моему, в C# невозможно получить небезопасный указатель на функцию. Для вызовов таких функций из неуправляемого кода всегда создаётся управляемая обёртка.

    Думал, думал, вот до чего додумался:

    using System;
    using System.Runtime.InteropServices;
    
    class Program
    {
        static double myFunc(double x, double y)
        {
            return x + y;
        }
    
        delegate double MyDel(double x, double y);
    
        static void Main(string[] args)
        {
            unsafe
            {
                MyDel del = new MyDel(myFunc);
                
                IntPtr ptr = Marshal.GetFunctionPointerForDelegate(del);
    
                // Получили указатель на ту самую функцию
                void* p = ptr.ToPointer();
    
                var d = (MyDel)Marshal.GetDelegateForFunctionPointer((IntPtr)p, typeof(MyDel));
    
                Console.WriteLine(d(2, 3));
            }
        }
    }
    


    В этом примере сначала из делегата получаем указатель на функцию, а потом из этого указателя опять получаем делегат, и только так можно вызвать исходный метод.

    Ничего лучше я придумать не смог.

    • Помечено в качестве ответа asdfxcbneftyherwe 23 октября 2011 г. 8:02
    23 октября 2011 г. 2:40
  • Указатель нужен потому, что так сказано в задании.


    Емое, чем люди занимаются... "так сказано в задании".

    Либо задание у вас не для C#, либо преподаватель сишарпа не знает.

    В любом случае ерундой вы занимаетесь.

    23 октября 2011 г. 6:50
    Отвечающий
  • Да не, у нас то в универе C++, а я пишу на C#, вот и приходится подстраиваться под задания. Конечно можно использовать обычные делегаты, но

    1) объяснять преподу что это такое - долго

    2) мне интересно попробовать это с указателями


    MSDN AA User
    23 октября 2011 г. 7:53
  • Да не, у нас то в универе C++, а я пишу на C#, вот и приходится подстраиваться под задания. Конечно можно использовать обычные делегаты, но

    1) объяснять преподу что это такое - долго

    2) мне интересно попробовать это с указателями



    С++ и C# совершенно разные языки.
    23 октября 2011 г. 7:54
    Отвечающий
  • Позволю себе возразить. Синтаксис одинаковый. С# наследник С++. Так что совершенно разные - это неверно.
    MSDN AA User
    23 октября 2011 г. 9:11
  • Синтаксис одинаковый. С# наследник С++. Так что совершенно разные - это неверно.
    Угу. А C++ - наследник C, синтаксис похож. А Nemerle - наследник C#, синтаксис похож. Вывод: Nemerle и C - одно и то же! :D
    23 октября 2011 г. 15:32
  • Позволю себе возразить. Синтаксис одинаковый. С# наследник С++. Так что совершенно разные - это неверно.
    MSDN AA User

    Синтаксис это не главное в языке. Это лет 30 назад был бум всевозможных синтаксисов. А потом разработчики поняли, что главное не синтаксис, а парадигма языка. И сейчас практически никто синтаксисов не придумывает, берут просто сишный синтаксис, как наиболее распространенный, да и все. Например php и javascript тоже имеют си-подобный синтаксис, и что? Они похожи на C++? Аналогично, сишарп заимствует идеи джавы и делфи но аж никак не C++.
    23 октября 2011 г. 22:14
    Отвечающий