2012-02-26 3 views
2

Я экспортирую некоторые классы C++ в Lua с помощью SWIG. Я предрек повышение :: файловая система :: путь в файле интерфейса SWIG как это:SWIG: Lua - Передача экземпляра C++ в качестве параметра функции lua

namespace boost 
{ 
    namespace filesystem 
    { 
     class path {}; 
    } 
} 

Теперь я хочу, чтобы вызвать функцию объявленную в Lua скрипт, который должен взять повышающий :: файловую систему :: Path & как чтобы передать его другому объекту. Мне нужно только пройти путь к объекту. Мне не нужно использовать какие-либо функции из объекта пути.

function on_path_selected(the_path) 
    another_object:set_path(the_path) 
end 

Я собираюсь вызвать функцию Lua из C++, используя его индекс.

lua_rawgeti(L, LUA_REGISTRYINDEX, m_function_index); 
lua_push[SOMETHING](L, path_object); // <-- HOW TO ? 
lua_pcall(L,1,0,0) 

ВОПРОС: Как нажать boost :: filesystem :: путь как параметр функции Lua?

ответ

5

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

Это не значит, что это невозможно, просто сложно.

Все объекты C++ на основе SWIG передаются через Lua в качестве указателей. Таким образом, вопрос собственности - вопрос; вы не можете просто перетащить указатель на объект стека в Lua.

Самый безопасный способ сделать это - передать новую копию объекта в Lua. Таким образом, Lua владеет указателем. SWIG будет знать, что Lua владеет указателем и приложит к нему надлежащий механизм сбора мусора, чтобы очистить его. Так что все должно быть хорошо, память мудрая.

Но для этого требуется должным образом «бокс» (из-за отсутствия лучшего термина), которые возражают так, как это делает SWIG. Для этого требуется использование определенных макросов SWIG.

Учитывая то, как вы связали path типа к Swig, вы могли бы сделать что-то вроде этого, чтобы вставить его на Lua стек:

swig_type_info *pathType = SWIG_TypeQuery("boost::filesystem::path *"); 
boost::filesystem::path *pArg = new boost::filesystem::path(the_path); 
SWIG_NewPointerObj(L, pArg, outputType, 1); 

SWIG_TypeQuery выбирает тип любого объекта, который был привязан по SWIG к Lua. Этот информационный объект типа необходим для SWIG_NewPointerObj, который берет указатель на этот тип. Оба эти макроса. SWIG_NewPointerObj дает Lua право собственности на указатель; Сборщик мусора Lua удалит его благодаря метатегам SWIG. Также SWIG_NewPointerObj толкает объект на стек lua_State.

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

Теперь, если вы введете этот код в свой проект, вероятность того, что вы получите ошибку компиляции, когда компилятор увидит swig_type_info. Этот тип определяется внутренним в исходном файле, сгенерированном командной строкой SWIG.

У вас есть два варианта:

  1. Поместите этот исходный код в сам .swig файл. Да, действительно.Вы можете определить регулярные функции C++ там, внутри разделов разделов (блоки %{%}). Эти функции будут скопированы непосредственно в сгенерированный код SWIG. Вы можете получить к ним доступ, поставив прототипы в заголовки. Это самый простой и простой способ работы. Это часто используется для создания специальных интерфейсов, где ранее существовавшая функция C++ не подходит для Lua API (или просто не существует).

  2. Вы можете создать соответствующий заголовок, содержащий эти определения, с аргументом -external-runtime. Это должен быть другой шаг выполнения SWIG с шага, который генерирует .cpp-файл. Смотрите, он фактически не обрабатывает файл SWIG или что-то еще. Все, что нужно, это целевой язык (-lua) и используете ли вы C++ (-c++). У вас есть только команда, которая делает swig -c++ -lua -external-runtime someheader.h, и это все, что вам нужно для получения типов и макросов.

    Включите этот заголовок в любой источник, который вы хотите прикрепить SWIG-связанные объекты Lua в.

+0

Спасибо за этот великий ответ. В настоящее время я копаю созданный исходный файл SWIG cpp, и я могу полностью оценить уровень правильности того, что вы описали. Да, похоже, будет долгий путь найти элегантный способ заставить эту работу. спасибо! EDIT: Я укажу это как ответ, как только увижу кнопку для этого. – damian

Смежные вопросы