У меня есть небольшое приложение, которое использует Lua, связанный как dll (не статический). Я хочу загрузить свою собственную библиотеку DLL, написанную на C ++, через Lua, используя package.loadlib (libname, funcname) . Для этого мне нужно экспортировать функцию, которая следует протоколу Lua lua_CFunction . Очевидно, по этой причине я должен включить lua.h
в свой проект и использовать Lua ' s функции для передачи параметров и результатов. Итак, мои вопросы:
package.loadlib
или моя DLL после загрузки остается до тех пор, пока завершить выполнение lua scrpit или завершение работы приложения? Начиная с ваших конкретных вопросов:
Да, но только если ваша DLL неявно связана с ней. Будьте осторожны с этим, потому что, если вы случайно свяжете две копии виртуальной машины Lua с вашим приложением, это может привести к большой путанице. Если на то пошло, аналогичные проблемы применимы и к среде выполнения C. Я бы загрузил все приложение в Dependency Walker, чтобы убедиться, что оно относится только к одному экземпляру Lua DLL и одной единственной среде выполнения C.
Насколько я понимаю, package.loadlib()
отвечает только за загрузку и связывание с указанной функцией в указанной библиотеке.Пока возвращенный функциональный объект (представляющий названную вами lua_CFunction
) жив, DLL, безусловно, загружается. Если вы потеряете последнюю ссылку на функцию, то библиотека может быть доступна для сборки мусора, и если она будет собрана, она будет выгружена. В списке рассылки Lua-L говорилось о том, как именно гарантировать выгрузку конкретной DLL, если это вас беспокоит. В противном случае, если вы просто предполагаете, что DLL загружена, пока вы можете получить доступ к хранящейся в ней функции, все будет в порядке.
Позвольте мне добавить, что модульная система, построенная поверх этого, является гораздо лучшим способом расширения Lua с помощью кода C или C++. Глава 26 книги «Программирование на Lua» описывает это более подробно, и ссылка на эту главу находится в онлайн-копии первого издания (описывающего Lua 5.0). Обратите внимание, что модульная система немного изменилась в Lua 5.1 и снова в Lua 5.2. Получение копии второго или третьего издания PiL (доступного как в бумажной, так и в электронной форме во многих книжных магазинах) может быть полезным.
Вот краткое изложение: чтобы создать модуль с именем foo
на C, вы создаете foo.dll
, который экспортирует как минимум функцию с прототипом int luaopen_foo(lua_State *Л)
. Эта функция должна загрузить ваш модуль (обычно с помощью luaL_register()
в Lua 5.1, или luaL_newlib()
или luaL_setfuncs()
в Lua 5.2 для регистрации таблицы. полный функций C) и вернуть эту таблицу. На стороне Lua вы помещаете DLL куда-нибудь по пути, описанному в пакете .cpath
, а затем его можно загрузить с помощью кода вида local foo = require "foo"
. Существуют и другие тонкие различия между различными версиями Lua 5.x, но относительно просто создать код C, который можно скомпилировать для любой из них.
Поступая таким образом, вы получаете преимущество, заключающееся в том, что модуль можно загрузить из пути, его можно написать либо на C, либо на Lua, либо на их сочетании, и он хорошо взаимодействует с другими модулями. Вы также можете загрузить столько функций C, сколько вам нужно, одним вызовом require
.
Вы можете динамически ссылаться на ту же DLL Lua, что и в вашем приложении.
Что касается package.loadlib, я понятия не имею, как это работает. Читать источник ?