WedX - журнал о программировании и компьютерных науках

Как создать объект функции, совместимый с С++, в LUA?

Я думаю о том, как спроектировать свои API, я планирую иметь приложение C++ со слоем сценариев в LUA.

Для нескольких ключевых моментов в моем дизайне я хотел бы дать пользователю возможность создать объект функции, который представляет то, что он хочет сделать в LUA, а затем отправить этот объект функции из LUA в C/C++.

В псевдокоде на С++ у меня есть class T

class T {
...
int num1 = 0;
float num2 = 0.0f;
std::string str{"NONE"};
...
};

И я хотел бы манипулировать экземпляром T с function object, предоставленным LUA, вот так

void applyFunc(T t,F f){
f(t);
}

Проблема в том, что я не могу найти в LUA ничего, что создавало бы функциональный объект, такой как лямбда C++11 или std::function, или любой другой объект, который можно считать функциональным объектом.

На самом деле я хочу сказать: как определить объект функции, совместимый с C++, в LUA?

21.02.2014

  • В этой ситуации вам может помочь библиотека LuaBridge. 22.02.2014
  • @TimCooper, не могли бы вы привести рабочий пример для этого? Потому что у меня сложилось впечатление, что любое популярное решение LUA‹-›C++ действительно работает с C++ на LUA, а не наоборот. 22.02.2014
  • @ user2485710: заставить С++ вызывать функцию Lua не просто. Трудная часть - это когда вы хотите, чтобы код Lua мог манипулировать объектом C++, как в вашем примере. Это проблема, с которой помогают библиотеки. 22.02.2014
  • SWIG (www.swig.org) — это генератор кода, с помощью которого можно легко обернуть ваши классы C++ так, чтобы их можно было использовать из Lua. Затем вы создаете экземпляр интерпретатора Lua в своем приложении C++, выполняете код в интерпретаторе для загрузки вашего модуля Lua (созданного с помощью SWIG), а затем вы можете запускать сценарии Lua, которые используют ваши классы C++. У меня есть библиотека lua-icxx, которая выполняет основные функции (работа в процессе, так что YMMV - часть для интеграции с SWIG все еще находится только в SVN, релиза еще нет). 22.02.2014
  • @Schollii Я знаю SWIG, и это не то, что мне нужно. stackoverflow.com/questions/21944455/ 22.02.2014
  • Неясно, нужно ли вам знать, как передать функцию из Lua в C, или как написать код для применения функции к экземпляру класса C++, или как написать код, позволяющий функции читать и записывать экземпляр поля или как упаковать все это в вызываемый объект и вписать его в ваш дизайн C++. Пожалуйста, укажите, какие из них вы понимаете, а какие нет. 23.02.2014
  • @TomBlodget путь, по которому я хотел бы пройти, - это от LUA до C++. Ключевой узел, который мешает мне сделать это, - это то, как определить, создать, написать объект функции C++ в LUA, а не функцию, объект функции, что-то вроде лямбда, экземпляр std::function, но он будет создан в LUA . 23.02.2014
  • @user2485710 user2485710: напишите объект функции C++ в LUA. Вы не можете. Lua компилируется в байтовый код и работает на виртуальной машине на основе регистров. C++ (обычно) компилируется в собственный машинный код и работает на аппаратном процессоре. Вы не можете создать собственную функцию машинного кода из Lua. Однако вы можете легко достичь желаемой цели — манипулировать экземпляром T с помощью функционального объекта, предоставленного из LUA, даже используя предпочитаемый вами синтаксис (например, applyFunc(f,t)), — если вы слушаете ответы, которые вы нам дали. 24.02.2014
  • @ Грязь Я не отказываюсь от данных ответов, они просто не сосредоточены на моей основной мысли. Странно, что C++ ABI не считается допустимым протоколом от LUA. Это было бы очень полезно. 24.02.2014
  • @ user2485710: они просто не сосредоточены на моей основной мысли Они, 100%. Вам показали, как сделать именно то, что вы хотите сделать. C++ ABI не считается "допустимым протоколом" LUA А? Как вы думаете, как Lua вызывает функции, которые вы предоставляете ему из C++? Он написан на C. Конечно, сами функции Lua ему не соответствуют, они не являются нативным кодом, они представляют собой последовательность инструкции, которые получают обрабатывается собственным кодом (то есть интерпретатором Lua). 24.02.2014
  • @ Грязь, ты думаешь об инструкциях и регистрах, я думаю о том, как вызовы функций, методы и значения размещаются в памяти и как они реализуются. В любом случае, поскольку нет никакой возможности, я приму это. 24.02.2014
  • Я думаю обо всем вышеперечисленном: инструкциях, регистрах, стеке вызовов, указателях, выравнивании и т. д. -- все это используется внутри интерпретатора Lua, и все это совершенно не имеет значения. и фактически запрещен для языка Lua. И ничто из этого не имеет ни малейшего отношения к ответу на вашу проблему. Вы можете создавать методы в Lua, которым передается экземпляр класса C++. На самом деле, это очень распространенное использование Lua. 25.02.2014
  • @ Грязь, хорошо, но это не то, что мне нужно, это так просто. 25.02.2014
  • @ user2485710: это не то, что мне нужно. Это то, что вы просили. Судя по вопросу, ответы, которые вы получили, вероятно вам нужны. Это просто звучит так, будто вы почти ничего не знаете о динамических языках и вам нужно преодолеть этот горб. Если вы хотите динамически создавать функции во время выполнения, которые могут работать с объектом C++, вы абсолютно можете сделать это в Lua. Вы просто не собираетесь создавать собственный код во время выполнения для этого, а не Lua, Ruby, Python, Perl, JavaScript и т. д. 25.02.2014

Ответы:


1

Проблема в том, что я не могу найти в LUA ничего, что создавало бы объект функции, такой как лямбда C++11 или std::function, или любой другой объект, который можно считать объектом функции.

Это то, что делает ключевое слово function. Это < /em> лямбда. Достаточно просто передать их в C++ и позволить коду C++ вызывать их.

Что касается этого:

void applyFunc(T t,F f){  
   f(t);  
}  

В принципе это просто: поместите указатель объекта C++ в стек Lua как userdata и вызовите функцию Lua. Проблема в том, что код Lua ничего не может сделать с указателем C++.

Если вы хотите, чтобы код Lua мог манипулировать объектом, который вы ему передаете, вам нужно написать методы манипулятора на C++ и предоставить их Lua. Обычно вы делаете это, создавая метатаблицу для пользовательских данных.

Есть библиотеки, которые автоматически для C++. Если вы хотите сделать это вручную (мое предпочтение ), вам, вероятно, следует начать здесь.

Если вы погуглите «C++ object Lua __index», это должно привести к многочисленным примерам. Я мог бы написать пример позже, но сейчас я на работе.

21.02.2014
  • и как это вписывается в качестве эквивалента функционального объекта C++ и как сделать то, что я просил, с этим ключевым словом function? Насколько я знаю, это больше похоже на старую простую функцию C. 22.02.2014
  • @user2485710 user2485710 Функции Lua - это просто один тип значения. Вы можете проверить значение, чтобы увидеть, является ли его тип функцией. Если это так, вы можете вызвать его с любыми параметрами, которые вы хотите. Локальные и глобальные переменные, элементы таблицы (значения и ключи), параметры и возвращаемые значения могут иметь функции в качестве значений. Вы хотите, чтобы пользователь создал функцию, которая принимает один параметр t и позволяет ему вызывать для нее документированные методы. Lua позволяет это, используя позднее связывание, если хотите. Вам просто нужно написать связующий код на стороне C параметра userdata t. 22.02.2014
  • @TomBlodget лучшее, что я могу сделать, это использовать функцию C или указатель на функцию, мне нужен функциональный объект, что-то вроде лямбда C++ 11, пожалуйста, прочитайте вопрос. Ваши посты и комментарии интересны, но все они ОТ. 22.02.2014
  • Функции Lua являются лямбда-выражениями, и они являются замыканиями, способными переносить состояние. Ничто из этого не имеет отношения к вашему вопросу. Вы не продумываете, что f(t) на самом деле означает. Да, вы можете передать t (объект C++) в f (функция Lua), но вы должны предоставить f возможность манипулировать t из Lua, иначе это совершенно бесполезно. Кажется, что ваши глаза тускнеют, когда вы видите, что объект C++ привязывается к Lua, но это именно то, что вам нужно. Без него вы не сможете реализовать applyFunc. 23.02.2014
  • Новые материалы

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

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    © 2024 wedx.ru, WedX - журнал о программировании и компьютерных науках
    Для любых предложений по сайту: [email protected]