Это на самом деле довольно сложно. Ожидаемое использование 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.
У вас есть два варианта:
Поместите этот исходный код в сам .swig файл. Да, действительно.Вы можете определить регулярные функции C++ там, внутри разделов разделов (блоки %{
%}
). Эти функции будут скопированы непосредственно в сгенерированный код SWIG. Вы можете получить к ним доступ, поставив прототипы в заголовки. Это самый простой и простой способ работы. Это часто используется для создания специальных интерфейсов, где ранее существовавшая функция C++ не подходит для Lua API (или просто не существует).
Вы можете создать соответствующий заголовок, содержащий эти определения, с аргументом -external-runtime
. Это должен быть другой шаг выполнения SWIG с шага, который генерирует .cpp-файл. Смотрите, он фактически не обрабатывает файл SWIG или что-то еще. Все, что нужно, это целевой язык (-lua
) и используете ли вы C++ (-c++
). У вас есть только команда, которая делает swig -c++ -lua -external-runtime someheader.h
, и это все, что вам нужно для получения типов и макросов.
Включите этот заголовок в любой источник, который вы хотите прикрепить SWIG-связанные объекты Lua в.
Спасибо за этот великий ответ. В настоящее время я копаю созданный исходный файл SWIG cpp, и я могу полностью оценить уровень правильности того, что вы описали. Да, похоже, будет долгий путь найти элегантный способ заставить эту работу. спасибо! EDIT: Я укажу это как ответ, как только увижу кнопку для этого. – damian