A lightweight, header-only C++17 binding library for Lua.
A header-only C++ and Lua glue/bridge library (b stands for bridge). Built on modern C++17, bLua provides a clean, zero-overhead, and non-intrusive interface for seamless interoperability between C++ and Lua.
- Modern C++17: Leverages fold expressions and template metaprogramming for efficient compilation and zero runtime overhead.
- Header-only: Single header file
bLua.hwith no extra libraries to build—just drop it into your project and use. - Member Function Support: Easily binds regular functions, member functions, and
constmember functions. - Rich Type Support: Built-in support for
std::string_view,std::string, primitive types, and custom user classes. - Non-intrusive: No need to inherit from any base class or decorate classes with intrusive macros.
- Safe Lifetime Management: Uses Lua weak tables and userdata to track and manage C++ pointer lifecycles, preventing duplicate userdata creation and memory leaks.
- Modern CMake: First-class support for
find_package(bLua),FetchContent, and CTest unit testing.
Register a class and its member functions (supports global functions, member functions, const member functions, etc.):
#include "bLua.h"
// Register global functions
bLua::reg_global_func(L, "newA", newA);
bLua::reg_global_func(L, "printA", printA);
// Register class and member functions
bLua::reg_class<A>(L);
bLua::reg_class_func(L, "get_this", &A::get_this);
bLua::reg_class_func(L, "get_int", &A::get_int);
bLua::reg_class_func(L, "get_int_const", &A::get_int_const); // Supports const member functions
bLua::reg_class_func(L, "set_int", &A::set_int);
bLua::reg_class_func(L, "get_string", &A::get_string);
bLua::reg_class_func(L, "set_string", &A::set_string);Then invoke them in Lua:
-- Create an instance
local a = newA()
-- Call member functions
a:set_int(123)
print("a:get_int() ", a:get_int())
-- Call string functions
a:set_string("abc")
print("a:get_string() ", a:get_string())// Receive multiple return values
int output_int = 0;
std::string output_str;
uint64_t output_int64 = 0;
// Input arguments
int input_int = 123;
std::string input_str = "test";
// Call the function (supports 0 or more arguments)
auto err = bLua::call_lua_global_func(L, "global_func_name",
std::tie(output_int, output_str, output_int64),
input_int, input_str);
// Check if call succeeded
if (err) {
// Error occurred, print error message
printf("ret error: %s\n", err.value().c_str());
} else {
// Succeeded, print returned values
printf("%d %s %llu\n", output_int, output_str.c_str(), output_int64);
}If the Lua function is located inside nested tables:
function _G.test.func.test(a, b)
return a - b
endCall it from C++ via a path of table keys:
auto err = bLua::call_lua_table_func(L, {"_G", "test", "func"}, "test",
std::tie(output_int),
input_int, input_int2);For complete examples, refer to test/test.cpp and test/test.lua.
Copy bLua.h into your project directory and #include "bLua.h".
include(FetchContent)
FetchContent_Declare(
bLua
GIT_REPOSITORY https://github.com/esrrhs/bLua.git
GIT_TAG master
)
FetchContent_MakeAvailable(bLua)
target_link_libraries(your_target PRIVATE bLua::bLua)After installing, use it directly in CMakeLists.txt:
find_package(bLua REQUIRED)
target_link_libraries(your_target PRIVATE bLua::bLua)Build and run tests using modern CMake:
# Configure
cmake -B build -DCMAKE_BUILD_TYPE=Release
# Build test executable
cmake --build build
# Run unit tests
ctest --test-dir build --output-on-failure