├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── example ├── main.cpp └── test.lua ├── lua ├── main.lua ├── module.lua └── test.lua └── src ├── Lua-in-cpp ├── BaseFunction.cpp ├── BaseFunction.hpp ├── Lua.cpp ├── Lua.hpp ├── LuaFunction.cpp ├── LuaFunction.hpp ├── NonVoidFunction.cpp ├── NonVoidFunction.hpp ├── VoidFunction.cpp └── VoidFunction.hpp └── LuaInCpp.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Others 35 | .vscode/ 36 | 37 | yeet -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ANTI-CAPITALIST SOFTWARE LICENSE (v 1.4) 2 | 3 | Copyright © 2020, 2021, 2022, 2023 matteov 4 | 5 | This is anti-capitalist software, released for free use by individuals and organizations that do not operate by capitalist principles. 6 | 7 | Permission is hereby granted, free of charge, to any person or organization (the "User") obtaining a copy of this software and associated documentation files (the "Software"), to use, copy, modify, merge, distribute, and/or sell copies of the Software, subject to the following conditions: 8 | 9 | 1. The above copyright notice and this permission notice shall be included in all copies or modified versions of the Software. 10 | 11 | 2. The User is one of the following: 12 | a. An individual person, laboring for themselves 13 | b. A non-profit organization 14 | c. An educational institution 15 | d. An organization that seeks shared profit for all of its members, and allows non-members to set the cost of their labor 16 | 17 | 3. If the User is an organization with owners, then all owners are workers and all workers are owners with equal equity and/or equal vote. 18 | 19 | 4. If the User is an organization, then the User is not law enforcement or military, or working for or under either. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLE = test 2 | 3 | SHARED_NAME = libluaincpp.so 4 | 5 | STATIC_NAME = libluaincpp.a 6 | 7 | HEADERS = src/LuaInCpp.hpp\ 8 | src/Lua-in-cpp/ 9 | 10 | SRC = src/Lua-in-cpp/Lua.cpp\ 11 | src/Lua-in-cpp/BaseFunction.cpp\ 12 | src/Lua-in-cpp/VoidFunction.cpp\ 13 | src/Lua-in-cpp/NonVoidFunction.cpp\ 14 | src/Lua-in-cpp/LuaFunction.cpp 15 | 16 | OBJ = $(SRC:.cpp=.o) 17 | 18 | SRC_EXAMPLE = example/main.cpp 19 | 20 | OBJ_EXAMPLE = $(SRC_EXAMPLE:.cpp=.o) 21 | 22 | OBJ_SHARED = $(SRC:.cpp=_shared.o) 23 | 24 | CXXFLAGS = -W -Wall -Wextra --std=c++20 -iquote src 25 | 26 | LDFLAGS = -llua -ldl 27 | 28 | all: $(BIN_TEST) $(SHARED_NAME) $(STATIC_NAME) 29 | 30 | %_shared.o: %.cpp 31 | g++ $(CXXFLAGS) -fPIC -c -o $@ $< 32 | 33 | $(SHARED_NAME): $(OBJ_SHARED) 34 | g++ -shared -o $@ $(OBJ_SHARED) $(LDFLAGS) 35 | 36 | $(STATIC_NAME): $(OBJ) 37 | ar rc $@ $(OBJ) 38 | 39 | $(EXAMPLE): $(SHARED_NAME) $(OBJ_EXAMPLE) 40 | g++ -o $(EXAMPLE) $(OBJ_EXAMPLE) -Wall -Wextra -L. -lluaincpp -llua 41 | 42 | install: $(STATIC_NAME) 43 | cp -r $(HEADERS) /usr/local/include/ 44 | cp $(STATIC_NAME) /usr/local/lib 45 | ldconfig 46 | 47 | uninstall: 48 | rm -rf /usr/local/include/LuaInCpp.hpp 49 | rm -rf /usr/local/include/Lua-in-cpp 50 | rm -rf /usr/local/lib/$(STATIC_NAME) 51 | 52 | clean: 53 | rm -rf $(OBJ) 54 | rm -rf $(OBJ_SHARED) 55 | 56 | fclean: clean 57 | rm -rf $(SHARED_NAME) 58 | rm -rf $(STATIC_NAME) 59 | rm -rf $(EXAMPLE) 60 | 61 | re: fclean $(EXAMPLE) 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lua in C++ 2 | 3 | ## A simple bridge between Lua's API and C++. 4 | 5 | This repository is still work in progress but starts to be useable. You can find classes to use Lua's API in C++ and use it to script things into your C++ programs. 6 | 7 | This has been tested with C++ 20 on g++, Lua 5.4 and Ubuntu 22.04. 8 | 9 | ## Installation 10 | 11 | Clone this repository and compile the static or shared library (see [this](#known-issues)) like this: 12 | 13 | ```sh 14 | make libluaincpp.a 15 | make libluaincpp.so 16 | ``` 17 | 18 | Then you're free to use and link it with your program. 19 | 20 | ## How to use 21 | 22 | Here is a a Lua file and a C++ file showing you some of the features that this library does, you can find these files in the `example` folder: 23 | 24 | ```lua 25 | function greets(name) 26 | print("[Lua] Hello "..name) 27 | end 28 | 29 | function my_sin_int(x) 30 | print("[Lua] "..math.sin(x)) 31 | end 32 | 33 | function is_true(b) 34 | print("[Lua] ", b == true) 35 | end 36 | 37 | function my_sin_float(x) 38 | print("[Lua] "..math.sin(x)) 39 | end 40 | 41 | function both_sin(x1, x2) 42 | my_sin_float(x1) 43 | my_sin_int(x2) 44 | end 45 | 46 | function all(name, b, f, i) 47 | greets(name) 48 | is_true(b) 49 | my_sin_float(f) 50 | my_sin_int(i) 51 | return 1234 52 | end 53 | 54 | function add_test() 55 | print("[Lua] "..mymath.add(1, 2)) 56 | end 57 | 58 | ``` 59 | 60 | ```cpp 61 | #include 62 | #include "LuaInCpp.hpp" 63 | 64 | // To call a C++ function in Lua, you have to use the Lua API 65 | // Here's an example: 66 | int add(lua_State *l) 67 | { 68 | int n = lua_gettop(l); // get the number of arguments 69 | 70 | if (n != 2) { 71 | lua_pushliteral(l, "bad number of arguments"); 72 | lua_error(l); 73 | } 74 | 75 | int a = lua_tointeger(l, 1); // get first argument 76 | int b = lua_tointeger(l, 2); // get second arument 77 | 78 | std::cout << "[C++] " << a << " + " << b << std::endl; 79 | lua_pushinteger(l, a + b); // the return value 80 | return 1; // number of argument returned 81 | } 82 | 83 | int main() 84 | { 85 | Lua l; 86 | l.openLibs(); 87 | 88 | l.add("add", &add, "mymath"); 89 | 90 | if (l.loadFile("test.lua")) { 91 | LuaFunction greets(l, "greets"); 92 | char *s = strdup("Frodo"); // works with not const too 93 | greets(s); 94 | 95 | LuaFunction my_sin(l, "my_sin_int"); 96 | long a = 0; // works with long too 97 | my_sin(a); 98 | 99 | LuaFunction my_sin_float(l, "my_sin_float"); 100 | my_sin_float(2.3); 101 | 102 | LuaFunction is_true(l, "is_true"); 103 | is_true(false); 104 | 105 | LuaFunction both_sin(l, "both_sin"); 106 | both_sin(2.3, 4); 107 | 108 | std::cout << std::endl; 109 | 110 | LuaFunction all(l, "all"); 111 | int b = all(s, false, 2.3, 4); 112 | std::cout << b << std::endl; 113 | 114 | l.call("main"); 115 | } 116 | } 117 | ``` 118 | 119 | Compile and run like this: 120 | ```sh 121 | make test 122 | ./test 123 | ``` 124 | 125 | And the output will be: 126 | ``` 127 | [Lua] Hello Frodo 128 | [Lua] 0.0 129 | [Lua] 0.74570521217672 130 | [Lua] false 131 | [Lua] 0.74570521217672 132 | [Lua] -0.75680249530793 133 | 134 | [Lua] Hello Frodo 135 | [Lua] false 136 | [Lua] 0.74570521217672 137 | [Lua] -0.75680249530793 138 | 1234 139 | 140 | [C++] 1 + 2 141 | [Lua] 3 142 | ``` 143 | 144 | ## What is currently being done ? 145 | 146 | This library is able to do: 147 | 148 | * Injecting C++ values, functions and tables in a lua instance 149 | * Call thoses C++ functions in lua 150 | * Call lua functions in C++ (cannot call functions with multiple return values for now) 151 | 152 | ## Known issues 153 | 154 | ### Why can't I compile it in a shared library ? 155 | 156 | To compile this project into a shared library, you must also have a shared library of lua itself. For that, you can go [here](https://www.lua.org/ftp/) to download the source code of your favorite version of lua and tweak the `Makefile` in the `src` folder to create a `liblua.so` and place it next to the `liblua.a` already installed on your system 157 | 158 | Then you can have this library in a shared format like that: 159 | ```sh 160 | make libluaincpp.so 161 | ``` 162 | 163 | ### Other issues 164 | 165 | If you have any idea on how to solve these problems or you want to contribute, please open an issue, I'll be happy to discuss it with you 166 | 167 | - Can't call lua functions with multiple return values 168 | - The library isn't installed on the machine for now, I believe it's only a few Makefile changes and it would be okay 169 | 170 | ## Support me 171 | 172 | You can star this repository, follow me or buy me a [coffee](https://ko-fi.com/pl0xxxy) 173 | -------------------------------------------------------------------------------- /example/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LuaInCpp.hpp" 3 | 4 | int add(lua_State *l) 5 | { 6 | int n = lua_gettop(l); // get the number of arguments 7 | 8 | if (n != 2) { 9 | lua_pushliteral(l, "bad number of arguments"); 10 | lua_error(l); 11 | } 12 | 13 | int a = lua_tointeger(l, 1); // get first arg 14 | int b = lua_tointeger(l, 2); // get second ard 15 | 16 | std::cout << "[C++] " << a << " + " << b << std::endl; 17 | lua_pushinteger(l, a + b); // the return value 18 | return 1; // number of argument returned 19 | } 20 | 21 | int main() 22 | { 23 | Lua l; 24 | l.openLibs(); 25 | 26 | l.add("add", &add, "mymath"); 27 | 28 | if (l.loadFile("example/test.lua")) { 29 | LuaFunction greets(l, "greets"); 30 | char *s = strdup("Frodo"); 31 | greets(s); 32 | 33 | LuaFunction my_sin(l, "my_sin_int"); 34 | long a = 0; 35 | my_sin(a); 36 | 37 | LuaFunction my_sin_float(l, "my_sin_float"); 38 | my_sin_float(2.3); 39 | 40 | LuaFunction is_true(l, "is_true"); 41 | is_true(false); 42 | 43 | LuaFunction both_sin(l, "both_sin"); 44 | both_sin(2.3, 4); 45 | 46 | std::cout << std::endl; 47 | 48 | LuaFunction all(l, "all"); 49 | int b = all(s, false, 2.3, 4); 50 | std::cout << b << std::endl; 51 | 52 | std::cout << std::endl; 53 | 54 | LuaFunction add_test(l, "add_test"); 55 | add_test(); 56 | 57 | free(s); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /example/test.lua: -------------------------------------------------------------------------------- 1 | function greets(name) 2 | print("[Lua] Hello "..name) 3 | end 4 | 5 | function my_sin_int(x) 6 | print("[Lua] "..math.sin(x)) 7 | end 8 | 9 | function is_true(b) 10 | print("[Lua] ", b == true) 11 | end 12 | 13 | function my_sin_float(x) 14 | print("[Lua] "..math.sin(x)) 15 | end 16 | 17 | function both_sin(x1, x2) 18 | my_sin_float(x1) 19 | my_sin_int(x2) 20 | end 21 | 22 | function all(name, b, f, i) 23 | greets(name) 24 | is_true(b) 25 | my_sin_float(f) 26 | my_sin_int(i) 27 | return 1234 28 | end 29 | 30 | function add_test() 31 | print("[Lua] "..mymath.add(1, 2)) 32 | end 33 | -------------------------------------------------------------------------------- /lua/main.lua: -------------------------------------------------------------------------------- 1 | function love.update(dt) 2 | print("ok") 3 | end 4 | 5 | function love.draw() 6 | end 7 | -------------------------------------------------------------------------------- /lua/module.lua: -------------------------------------------------------------------------------- 1 | function hello(name) 2 | print("Hello "..name) 3 | end 4 | 5 | function main() 6 | mod = {} 7 | mod.greets = hello 8 | mod.weather = "sunny" 9 | mod.temperature = 24 10 | mod.unit = "Celsius" 11 | 12 | mod.greets("Frodo") 13 | print(mod.unit) 14 | end 15 | 16 | main() 17 | -------------------------------------------------------------------------------- /lua/test.lua: -------------------------------------------------------------------------------- 1 | function hello() 2 | print("[Lua] Hello World") 3 | end 4 | 5 | function greets(name) 6 | print("[Lua] Hello "..name) 7 | end 8 | 9 | function printBoth(a, b) 10 | print("[Lua] "..a.." "..b) 11 | end 12 | 13 | function nope() 14 | return 1, 2 15 | end 16 | 17 | function add(nb1, nb2) 18 | print("[Lua] add "..nb1.." "..nb2) 19 | return nb1 + nb2 20 | end 21 | 22 | function dump(o) 23 | if type(o) == 'table' then 24 | local s = '{ ' 25 | for k,v in pairs(o) do 26 | if type(k) ~= 'number' then k = '"'..k..'"' end 27 | s = s .. '['..k..'] = ' .. dump(v) .. ',' 28 | end 29 | return s .. '} ' 30 | else 31 | return tostring(o) 32 | end 33 | end 34 | 35 | function main() 36 | hello() 37 | greets("Frodo") 38 | yeet._yeet() 39 | a, b = nope() 40 | print(a, b) 41 | end 42 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/BaseFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "BaseFunction.hpp" 2 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/BaseFunction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Lua.hpp" 7 | 8 | template< class > 9 | class BaseFunction; 10 | 11 | template 12 | struct helper; 13 | 14 | template<> 15 | struct helper 16 | { 17 | static void push(Lua &l, lua_Integer arg) { lua_pushinteger(getState(l), arg); } 18 | }; 19 | 20 | template<> 21 | struct helper 22 | { 23 | static void push(Lua &l, const char * arg) { lua_pushstring(getState(l), arg); } 24 | }; 25 | 26 | template<> 27 | struct helper 28 | { 29 | static void push(Lua &l, lua_Number arg) { lua_pushnumber(getState(l), arg); } 30 | }; 31 | 32 | template<> 33 | struct helper 34 | { 35 | static void push(Lua &l, bool arg) { lua_pushboolean(getState(l), arg); } 36 | }; 37 | 38 | template<> 39 | struct helper 40 | { 41 | static void push(Lua &l, void *arg) { lua_pushlightuserdata(getState(l), arg); } 42 | }; 43 | 44 | template< typename T, typename ...Args > 45 | class BaseFunction < T(Args...)> 46 | { 47 | friend class Lua; 48 | 49 | public: 50 | BaseFunction(Lua &l, const std::string &fname) : 51 | _inst(l), _fname(fname), _nbArg(0) 52 | { 53 | //std::cout << _fname << std::endl; 54 | } 55 | virtual ~BaseFunction() = default; 56 | 57 | virtual T operator()(Args...) = 0; 58 | 59 | // virtual T operator()(Args... args) 60 | // { 61 | // lua_getglobal(getState(_inst), _fname.c_str()); 62 | // intern(args...); 63 | // int a = lua_tointeger(getState(_inst), -1); 64 | // lua_pop(getState(_inst), 1); 65 | // return a; 66 | // } 67 | 68 | protected: 69 | template< typename U, typename ...InternArgs > 70 | void intern(U arg, InternArgs... args) 71 | { 72 | static_assert(std::is_same_v || std::is_same_v 73 | || std::is_same_v || std::is_same_v 74 | || std::is_same_v); 75 | _nbArg++; 76 | //std::cout << "arg: " << arg << std::endl; 77 | helper::push(_inst, arg); 78 | intern(args...); 79 | } 80 | 81 | template< typename U > 82 | void intern(U arg) 83 | { 84 | static_assert(std::is_same_v || std::is_same_v 85 | || std::is_same_v || std::is_same_v 86 | || std::is_same_v); 87 | _nbArg++; 88 | //std::cout << "final arg: " << arg << std::endl; 89 | helper::push(_inst, arg); 90 | lua_call(getState(_inst), _nbArg, 1); 91 | } 92 | 93 | void intern() 94 | { 95 | lua_call(getState(_inst), 0, 0); 96 | } 97 | 98 | Lua &_inst; 99 | const std::string _fname; 100 | int _nbArg; 101 | }; 102 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/Lua.cpp: -------------------------------------------------------------------------------- 1 | #include "Lua.hpp" 2 | 3 | Lua::Lua() 4 | { 5 | _state = luaL_newstate(); 6 | if (!_state) 7 | throw; 8 | } 9 | 10 | Lua::~Lua() 11 | { 12 | lua_close(_state); 13 | } 14 | 15 | void Lua::openLibs() const 16 | { 17 | luaL_openlibs(_state); 18 | } 19 | 20 | void Lua::reset() 21 | { 22 | lua_close(_state); 23 | _state = luaL_newstate(); 24 | if (!_state) 25 | throw; 26 | } 27 | 28 | bool Lua::loadFile(const std::string &filename) 29 | { 30 | if (luaL_dofile(_state, filename.c_str()) != LUA_OK) { 31 | std::cerr << lua_tostring(_state, -1) << std::endl; 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | bool Lua::loadScript(const std::string &script) const 38 | { 39 | if (luaL_dostring(_state, script.c_str()) != LUA_OK) { 40 | std::cerr << lua_tostring(_state, -1) << std::endl; 41 | return false; 42 | } 43 | return true; 44 | } 45 | 46 | void Lua::registerModule(const std::string &modName, const luaL_Reg *functions) const 47 | { 48 | lua_getglobal(_state, modName.c_str()); 49 | if (!lua_istable(_state, -1)) { 50 | lua_newtable(_state); 51 | } 52 | luaL_setfuncs(_state, functions, 0); 53 | lua_setglobal(_state, modName.c_str()); 54 | } 55 | 56 | void Lua::add(const std::string &name, lua_CFunction f, const std::string &modName) 57 | { 58 | if (modName == "") { 59 | lua_pushcfunction(_state, f); 60 | lua_setglobal(_state, name.c_str()); 61 | } else { 62 | lua_getglobal(_state, modName.c_str()); // get a name on the stack (may be a new or existing table) 63 | if (!lua_istable(_state, -1)) // create a table if it is not already 64 | lua_newtable(_state); 65 | lua_pushstring(_state, name.c_str()); // index of the value in the table 66 | lua_pushcfunction(_state, f); // value to be set 67 | lua_settable(_state, -3); // modName.name = f 68 | lua_setglobal(_state, modName.c_str()); // say that the table is now an accessible variable 69 | } 70 | } 71 | 72 | void Lua::add(const std::string &name, lua_Number n, const std::string &modName) 73 | { 74 | if (modName == "") { 75 | lua_pushnumber(_state, n); 76 | lua_setglobal(_state, name.c_str()); 77 | } else { 78 | lua_getglobal(_state, modName.c_str()); 79 | if (!lua_istable(_state, -1)) 80 | lua_newtable(_state); 81 | lua_pushstring(_state, name.c_str()); 82 | lua_pushnumber(_state, n); 83 | lua_settable(_state, -3); 84 | lua_setglobal(_state, modName.c_str()); 85 | } 86 | } 87 | 88 | void Lua::add(const std::string &name, lua_Integer i, const std::string &modName) 89 | { 90 | if (modName == "") { 91 | lua_pushinteger(_state, i); 92 | lua_setglobal(_state, name.c_str()); 93 | } else { 94 | lua_getglobal(_state, modName.c_str()); 95 | if (!lua_istable(_state, -1)) 96 | lua_newtable(_state); 97 | lua_pushstring(_state, name.c_str()); 98 | lua_pushinteger(_state, i); 99 | lua_settable(_state, -3); 100 | lua_setglobal(_state, modName.c_str()); 101 | } 102 | } 103 | 104 | void Lua::add(const std::string &name, const char *s, const std::string &modName) 105 | { 106 | if (modName == "") { 107 | lua_pushstring(_state, s); 108 | lua_setglobal(_state, name.c_str()); 109 | } else { 110 | lua_getglobal(_state, modName.c_str()); 111 | if (!lua_istable(_state, -1)) 112 | lua_newtable(_state); 113 | lua_pushstring(_state, name.c_str()); 114 | lua_pushstring(_state, s); 115 | lua_settable(_state, -3); 116 | lua_setglobal(_state, modName.c_str()); 117 | } 118 | } 119 | 120 | void Lua::add(const std::string &name, void *data, const std::string &modName) 121 | { 122 | if (modName == "") { 123 | lua_pushlightuserdata(_state, data); 124 | lua_setglobal(_state, name.c_str()); 125 | } else { 126 | lua_getglobal(_state, modName.c_str()); 127 | if (!lua_istable(_state, -1)) 128 | lua_newtable(_state); 129 | lua_pushstring(_state, name.c_str()); 130 | lua_pushlightuserdata(_state, data); 131 | lua_settable(_state, -3); 132 | lua_setglobal(_state, modName.c_str()); 133 | } 134 | } 135 | 136 | bool Lua::call(const std::string &name) 137 | { 138 | lua_getglobal(_state, name.c_str()); 139 | if (lua_pcall(_state, 0, 0, 0) != LUA_OK) { 140 | std::cerr << lua_tostring(_state, -1) << std::endl; 141 | return false; 142 | } 143 | return true; 144 | } 145 | 146 | /* 147 | 148 | void Lua::registerFunction(const std::string &name, const lua_CFunction f) 149 | { 150 | lua_pushcfunction(_state, f); 151 | lua_setglobal(_state, name.c_str()); 152 | } 153 | 154 | void Lua::registerModule(const std::string &moduleName, const luaL_Reg *functions) 155 | { 156 | lua_getglobal(_state, moduleName.c_str()); 157 | if (!lua_istable(_state, -1)) { 158 | lua_newtable(_state); 159 | } 160 | luaL_setfuncs(_state, functions, 0); 161 | lua_setglobal(_state, moduleName.c_str()); 162 | } 163 | 164 | void Lua::registerModule(const std::string &moduleName, LuaModule &module) 165 | { 166 | lua_getglobal(_state, moduleName.c_str()); 167 | if (!lua_istable(_state, -1)) { 168 | lua_newtable(_state); 169 | } 170 | luaL_setfuncs(_state, module.getFunctions(), 0); 171 | lua_setglobal(_state, moduleName.c_str()); 172 | } 173 | 174 | */ -------------------------------------------------------------------------------- /src/Lua-in-cpp/Lua.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" 4 | { 5 | #include 6 | #include 7 | #include 8 | } 9 | 10 | #include 11 | #include 12 | 13 | class Lua 14 | { 15 | public: 16 | Lua(); 17 | ~Lua(); 18 | 19 | void openLibs() const; // open lua libraries 20 | void reset(); // reset the internal state, create a new one 21 | bool loadFile(const std::string &); // load a .lua file 22 | bool loadScript(const std::string &) const; // load a string of lua 23 | 24 | // Todo: multiple registerModule() to register a bunch of functions or values in one go 25 | void registerModule(const std::string &, const luaL_Reg *) const; 26 | 27 | void add(const std::string &, lua_CFunction, const std::string & = ""); 28 | void add(const std::string &, lua_Number, const std::string & = ""); 29 | void add(const std::string &, lua_Integer, const std::string & = ""); 30 | void add(const std::string &, const char *, const std::string & = ""); 31 | void add(const std::string &, void *, const std::string & = ""); 32 | 33 | bool call(const std::string &); // call a lua function in C++ 34 | 35 | private: 36 | friend lua_State *getState(Lua &l) { return l._state; } 37 | 38 | // friend void pushOnStackInt(Lua &l, lua_Integer arg) { lua_pushinteger(l._state, arg); } 39 | // friend void pushOnStackNum(Lua &l, lua_Number arg) { lua_pushnumber(l._state, arg); } 40 | // friend void pushOnStackBool(Lua &l, bool arg) { lua_pushboolean(l._state, arg); } 41 | // friend void pushOnStackString(Lua &l, const char *arg) { lua_pushstring(l._state, arg); } 42 | // friend void pushOnStackPtr(Lua &l, void *arg) { lua_pushlightuserdata(l._state, arg); } 43 | // friend void pushOnStackNil(Lua &l) { lua_pushnil(l._state); } 44 | 45 | lua_State *_state; 46 | }; 47 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/LuaFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "LuaFunction.hpp" 2 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/LuaFunction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NonVoidFunction.hpp" 6 | #include "VoidFunction.hpp" 7 | 8 | template< class T, class ...Args > 9 | using DerivingFunction = typename std::conditional< 10 | std::is_void::value, 11 | VoidFunction< void(Args...) >, 12 | NonVoidFunction< T(Args...) > 13 | >::type; 14 | 15 | template< class > 16 | class LuaFunction; 17 | 18 | template< class T, class ...Args > 19 | class LuaFunction < T(Args...) > : public DerivingFunction 20 | { 21 | public: 22 | LuaFunction(Lua &l, const std::string &fname) : 23 | DerivingFunction(l, fname) 24 | {} 25 | }; 26 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/NonVoidFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "NonVoidFunction.hpp" 2 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/NonVoidFunction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BaseFunction.hpp" 4 | 5 | template< class > 6 | class NonVoidFunction; 7 | 8 | template< class T, class ...Args > 9 | class NonVoidFunction < T(Args...) > : public BaseFunction 10 | { 11 | public: 12 | NonVoidFunction(Lua &l, const std::string &fname) : 13 | BaseFunction(l, fname) 14 | {} 15 | 16 | T operator()(Args... args) override 17 | { 18 | //std::cout << "T operator()" << std::endl; 19 | lua_getglobal(getState(this->_inst), this->_fname.c_str()); 20 | this->intern(args...); 21 | int a = lua_tointeger(getState(this->_inst), -1); 22 | lua_pop(getState(this->_inst), 1); 23 | return a; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/VoidFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "VoidFunction.hpp" 2 | -------------------------------------------------------------------------------- /src/Lua-in-cpp/VoidFunction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BaseFunction.hpp" 4 | 5 | template< class > 6 | class VoidFunction; 7 | 8 | template< class ...Args > 9 | class VoidFunction : public BaseFunction 10 | { 11 | public: 12 | VoidFunction(Lua &l, const std::string &fname) : 13 | BaseFunction(l, fname) 14 | {} 15 | 16 | void operator()(Args... args) override 17 | { 18 | //std::cout << "void operator()" << std::endl; 19 | lua_getglobal(getState(this->_inst), this->_fname.c_str()); 20 | this->intern(args...); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /src/LuaInCpp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Lua-in-cpp/Lua.hpp" 4 | #include "Lua-in-cpp/LuaFunction.hpp" 5 | --------------------------------------------------------------------------------