Я скомпилировал консольную хост-программу, написанную на c / c ++ (у меня нет исходников). Хост-программа поддерживает скрипты lua (возможно, с использованием виртуальной машины lua). Хост-программа загрузки библиотек lua
luaopen_base
luaopen_table
luaopen_string
luaopen_math
luaopen_debug
и разрешить перезагрузку всех скриптов lua.
Можно ли вызвать любую функцию хоста c / c ++ из скрипта lua по адресу функции (получил их из внешнего отладчика в программе хоста)?
Можно ли в этом случае загрузить какие-либо скомпилированные библиотеки C / C ++ из lua и вызвать их функции?
Один человек на другом форуме написал этот код для этого вопроса
// re = callClientFunction(addr, { args }, 'cdecl')
// re = callClientFunction(method, { obj, arg1 }, 'this')
// re = callClientFunction(0x08, { obj, arg1 }, 'this') = obj->vtable[2]->(arg1)
inline int callCdeclFunction(lua::State* L, uintptr_t addr, const std::vector<lua::Integer>& args)
{
typedef lua::Integer __cdecl cf0();
typedef lua::Integer __cdecl cf1(lua::Integer);
typedef lua::Integer __cdecl cf2(lua::Integer, lua::Integer);
typedef lua::Integer __cdecl cf3(lua::Integer, lua::Integer, lua::Integer);
typedef lua::Integer __cdecl cf4(lua::Integer, lua::Integer, lua::Integer, lua::Integer);
typedef lua::Integer __cdecl cf5(lua::Integer, lua::Integer, lua::Integer, lua::Integer, lua::Integer);
lua::Integer re = 0;
switch(args.size())
{
case 0: re = reinterpret_cast<cf0*>(addr)(); break;
case 1: re = reinterpret_cast<cf1*>(addr)(args[0]); break;
case 2: re = reinterpret_cast<cf2*>(addr)(args[0], args[1]); break;
case 3: re = reinterpret_cast<cf3*>(addr)(args[0], args[1], args[2]); break;
case 4: re = reinterpret_cast<cf4*>(addr)(args[0], args[1], args[2], args[3]); break;
case 5: re = reinterpret_cast<cf5*>(addr)(args[0], args[1], args[2], args[3], args[4]); break;
default:
luaL_error(L, "%s: too many args (max %d, provided %d).\n", __func__, 5, args.size());
}
return re;
}
какие-либо идеи, как использовать его в скомпилированной хост-программе?
Правильный способ вызова функций C / C ++ из Lua — это написать код интерфейса для обмена данными в стеке Lua.
Однако существуют расширения для прямого вызова функций в общих библиотеках (.dll или .so).
Взгляните на библиотеку FFI (http://luajit.org/ext_ffi.html)
или Чужой Луа (http://alien.luaforge.net/) который использует библиотеку libffi (http://www.sourceware.org/libffi/)
Чтобы получить доступ к функциям C / C ++ в Lua, вы должны предоставить их через определенный API, Lua не загружает «обычные» dll (или .so, если вы, которые) напрямую. Вместо этого вы должны иметь промежуточную библиотеку, чтобы представить окружению Lua, какие функции Си будут доступны.
ура