Погода: -12°C
Samara24.Форум /Компьютеры Интернет Связь / Программирование /

Передача математической зависимости

  • Есть несколько неких математических зависимостей - функций - для расчета одной величины разными методами. Нужна такая реализация, при которой бы на основе каких-либо условий выбиралась та или иная функция (метод расчета). Основная сложность кроется в том, что содержание расчетов, соответствующих этим функциям заведомо не известно и должно передаваться программе через специальный интерфейс, принимающий параметры для расчета.
    Так вот, каким образом передать в этот интерфейс (принимающую функцию), например, такое:
    y = 2*x - 10

    Может, стоит, использовать указатель на функцию? Подскажите, кто сталкивался с подобной задачей.

  • Что же является критерием для выбора той или иной функции (метода)? Можно и switch использовать.

    Землю - крестьянам, фазу - электрикам!!

  • А на чем предполагается писать? С++?

  • Да. C++, среда VS6.
    Вообще, как я понял, для подобной реализации вполне приемлемо использовать указатель на функцию. Осталась единственная проблема, которую пока не знаю как решить - как прописать принимающей функции в качестве параметра указатель на функцию. При использовании ClassWizard'a вариант типа float y(float x, float (*func)(float xval)); не предусмотрен. А при попытке менять типы вручную возникают ошибки.

  • Во-первых, я все еще не понял тонкостей задания. Есть контроллер, который принимает некие параметры (фиксированный набор или произвольный?) и вызывает некую функцию (передается вместе с параметрами или должен сам выбрать?)

    Во-вторых, какого рода ошибки вылазят?

  • Есть контрол, функция(интерфейс) которого принимает:
    а) аргумент функции(некоей мат. зависимости)
    б) саму мат. зависимость

    В основном коде прописывается зависимость в виде функции:

    float y(float curx)
    {
    float yres = curx*curx;
    return yres;
    }

    Там же объявляется указатель на эту функцию:
    float (*ptr)(float x) = y;

    Далее в контрол передается значение аргумента, и зависимость, в соответствии с которой его нужно просчитать:

    ControlName->CalcFunc(2.15, ptr);


    Теперь нужно принять это значение функцией контрола:
    float CalcFunc(float xcur, float (*func)(float x))
    {
    float ydst = func(xcur);
    return ydst;
    }

    Добавление функции, видной извне, в контрол (функции интерфейса) производится через ClassWizard VS6. Там необходимо указать типы входящих данных путем выбора из списка. Как сделать это для случая с float (*func)(float x)) мне совсем неясно.
    Вот, собственно, формулировка вопроса.

  • 1. Если вариантов функций немного, это классический вариант паттерна Strategy.

    2. Если хочется поиметь любое выражение, то это Interpreter: распарсить строку по грамматике, поиметь AST-дерево и Command-ами/Visitor-ами его посчитать.

  • Думается, можно обойтись более простой реализацией. Неоднократно слышал положительные отзывы о design patterns, но в них я не секу.

    Зато появилась мысль, сводящая проблему к менее объемной.

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

    Из основной программы в контрол передается указатель она функцию, сконвернутый в int.

    Примерно так:
    float (*ptr)(float) = func; // func - функция, которую надо передать контролу

    MyControl1->MyFunction((int)ptr);

    Соответственно, теперь требуется на стороне контрола получить из переменной типа int значение типа "указатель на функцию".
    Как такое осуществить? Был бы какой-нить char* - там понятно:

    MyFunction(int myptr)
    {
    char* pp = (char*)myptr;
    }

    А указатель на функцию так просто, похоже, из адреса не получить.

  • Я сейчас проверить не могу, но могу дать такой совет - на ClassWizard забить, написать простой код ручками и посмотреть, что получится. Если нормально с английским, можно почитать здесь:
    http://www.function-pointer.org/fpt.html#passPtr

    P.S. Передача указателя, сконвертированного в int, покатит, но это уже лишнее.

  • 1. За линку спасибо, приятно было ознакомиться с хорошо структурированным материалом по теме. Однако принципиальных идей подчерпнуть не удалось - и так выполняю все по описанному там варианту передачи указателя на функцию в качестве аргумента.

    2. При попытке забить на ClassWizard вручную аргументы (их типы) функции замечательно редактируются в cpp и h файлах проекта,
    Там они после внесения изменений имеют вид:
    float (*func)(float).
    Однако в odl-файле, то есть там, где прописаны все эти выходы функций наружу (интерфейсы), ни в какую не канает вариант float (*func)(float)

    Ошибка: error MIDL2094 : [id] attribute is required : [( Parameter 'func' ) ]

    Блин, мне все равно думается, что можно таким способом реализовать данную функциональность. Тока как совладать с odl-связями?

  • Или подскажите кто-нить, как переконвертить адрес на указатель на функцию в сам указатель на функцию, то есть из int в float (*func)(float).

Записей на странице:

Перейти в форум

Модератор: