Вопрос

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

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

Спасибо.

Это было полезно?

Решение

Сложный библиотечный API часто может быть быстро и (почти) полностью обернут с помощью ГЛОТОК.Преимущество использования SWIG в этом случае заключается в том, что легко создавать оболочки на основе SWIG, которые позволяют использовать библиотеку в 18 основных языков включая Lua, Perl, Python, Ruby и Java, среди прочих.

Если Lua является вашей предпочтительной (и, возможно, единственной) заботой, то я бы рекомендовал научиться использовать luaL_register() в основе стратегии создания модулей Lua на C.Преимущество создания модуля таким способом заключается в том, что вы сохраняете все свои функции в одном пространстве имен без каких-либо накладных расходов.Вам нужно будет создать функцию-оболочку, которая соответствует соглашению о вызове функции Lua C (точно так же, как вы делаете с lua_register()) и это собирает аргументы Lua из стека, вызывает обернутую функцию и отправляет любое возвращаемое значение и выходные параметры обратно в стек Lua.Хороший обзор того, как это сделать, можно найти в книге "Программирование в Lua".Онлайн-копия первого издания обсуждает создание библиотеки в Глава 26, но был написан для Lua 5.0.Я настоятельно призываю всех, кто серьезно использует Lua, приобрести копию текущей версии PiL.

К сожалению, одна из областей, где Lua 5.1 больше всего отличается от 5.0, заключается в динамической загрузке модулей (как C, так и Lua) с require.

Вот полный (хотя и небольшой) пример библиотеки C, которая работает в Lua 5.1.Мы начинаем с реализации оболочки в файле C:

#include <lua.h>
#include <luaxlib.h>
#include <math.h>
#undef PI
#define PI (3.14159265358979323846)

static int l_sin (lua_State *L) {
    double r = luaL_checknumber(L,1);
    lua_pushnumber(L, sin(r));
    return 1;
}

static int l_cos (lua_State *L) {
    double r = luaL_checknumber(L,1);
    lua_pushnumber(L, cos(r));
    return 1;
}

static const struct luaL_reg smlib [] = {
    {"sin", l_sin},
    {"cos", l_cos},
    {NULL, NULL}  /* sentinel */
};

int luaopen_sm (lua_State *L) {
    luaL_openlib(L, "sm", smlib, 0);
    lua_pushnumber(L,PI);
    lua_rawset(L,-2,"pi");
    return 1;
}

Обратите внимание, в частности, что единственной функцией, которую необходимо экспортировать, является luaopen_sm(), имя которого должно соответствовать имени модуля , который будет использоваться с require, и с именем DLL-файла.С этим файлом, скомпилированным как DLL с именем sm.dll (вероятно, названный libsm.so в Unix-подобных системах), затем его можно загрузить и использовать в скрипте Lua, подобном этому:

require "sm"
print(sm.sin(sm.pi/3), sm.cos(sm.pi/3));

Этот пример, хотя и непроверенный, должен быть скомпилирован и запущен.Для полного примера, обертывающего большинство функций из math.h, смотрите на источник для math модуль это распространяется с помощью Lua.Поскольку эти тонкие оболочки содержат много повторяющегося кода, такие инструменты, как SWIG, часто способны создавать их, учитывая только объявление каждой функции.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top