Определить функцию C ++ во время выполнения - PullRequest
3 голосов
/ 09 февраля 2011

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

double xsquared(double x) {
    return x*x;
}

double expx(double x) {
    return exp(x);
}

double forward(double x, double h, double (*af)(double)) {
    double answer = (af(x+h)-af(x))/h;

    return answer;  
}

Где любая из первых двух функций может быть передана в качестве третьего аргумента. Однако я хотел бы передать пользовательский ввод (в действительном C ++), а не настраивать функции заранее. Любая помощь будет принята с благодарностью!

Ответы [ 8 ]

4 голосов
/ 09 февраля 2011

Исторически требуемая функциональность не была доступна в C ++. Обычный обходной путь - встроить интерпретатор для языка, отличного от C ++ (например, Lua и Python специально предназначены для интеграции в приложения C / C ++, чтобы разрешить их скриптинг), или создать новый язык, специфичный для вашего приложения, с помощью собственный синтаксический анализатор, компилятор и т. д. Однако, это меняется.

Clang - это новый компилятор с открытым исходным кодом, разработанный Apple для использования LLVM. Clang изначально разрабатывался так, чтобы его можно было использовать не только как компилятор, но и как библиотеку C ++, которую вы можете встраивать в свои приложения. Я сам не пробовал, но вы должны иметь возможность делать с Clang то, что вы хотите - вы бы связали его как библиотеку и попросили скомпилировать код, введенный вашими пользователями в приложение.

Вы можете попробовать , как команда ClamAV уже сделала это, чтобы новые определения вирусов могли быть написаны на C .

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

3 голосов
/ 09 февраля 2011

Поскольку C ++ является полностью скомпилированным языком, вы не сможете реально преобразовать пользовательский ввод в код, если не напишите собственный компилятор или интерпретатор.Но в этом примере можно создать простой интерпретатор для предметно-ориентированного языка, который будет представлять собой математические формулы.Все зависит от того, что вы хотите сделать.

1 голос
/ 09 февраля 2011

Лучшее решение - использовать встроенный язык, такой как lua ​​или python, для этого типа задач.См. Например Выбор встроенного языка для предложений.

1 голос
/ 09 февраля 2011

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

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

0 голосов
/ 04 октября 2012

Несмотря на то, что это кажется ударом, есть много людей, которые написали парсеры и интерпретаторы уравнений для c ++ и c, многие коммерческие, многие ошибочные, и все такие разные, как лица в толпе.Начнем с того, что ребята из колледжа пишут инфиксы для постфиксных переводчиков.Некоторые из этих систем используют паранетическую группировку с последующим размещением элементов в стеке, как в старой библиотеке HP STL.Я потратил 30 секунд и нашел это:

http://www.speqmath.com/tutorials/expression_parser_cpp/index.html

возможная строка поиска: "gcc 'равенство анализатора уравнений' в постфикс"

0 голосов
/ 09 февраля 2011

Вы можете использовать крошечный компилятор C в качестве библиотеки (libtcc).

Это позволяет вам скомпилировать произвольный код во время выполнения и загрузить его, но он работает только для C, неC ++.

Обычно единственный способ заключается в следующем:

  • Передать код компилятору и создать общий объект или DLL
  • Загрузить этот общий объект или DLL
  • Использовать функцию из этого общего объекта.
0 голосов
/ 09 февраля 2011

Ну, есть две вещи, которые вы можете сделать:

  1. Используйте все преимущества лямбды boost / C ++ 0x и определяйте функции во время выполнения.

  2. Если нужны только математические формулы, библиотеки типа muParser предназначены для преобразования строки в байт-код, который можно рассматривать как определение функции во время выполнения.

0 голосов
/ 09 февраля 2011

C ++, в отличие от некоторых других языков, таких как Perl, не способен выполнять интерпретацию во время выполнения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...