← 返回库列表

🌙 sol2 使用指南

现代 C++/Lua 绑定库

项目地址:https://github.com/ThePhD/sol2

官方文档:https://sol2.readthedocs.io/

📖 什么是 sol2?

sol2 是一个现代、轻量、高性能的 C++17/20 头文件库,用于在 C++ 和 Lua 之间进行无缝交互。它是 sol(Simple Object Lua)库的现代版本,提供了更简洁、更安全、更高效的 API。

🚀 安装方式

单头文件引入

// 下载 sol.hpp 并直接包含
#include "sol.hpp"

使用 vcpkg

vcpkg install sol2

使用 Conan

conan install sol2/3.3.0@

💡 基础使用

Hello World

#include <iostream>
#include "sol.hpp"

int main() {
    // 创建 Lua 状态
    sol::state lua;

    // 执行 Lua 代码
    lua.script("print('Hello from Lua!')");

    // 从 C++ 调用 Lua 函数
    lua.script("function greet(name) return 'Hello, ' .. name .. '!' end");
    std::string greeting = lua["greet"]("World");
    std::cout << greeting << std::endl;

    return 0;
}

从 C++ 向 Lua 传递数据

sol::state lua;

// 设置全局变量
lua["x"] = 24;
lua["y"] = 16;
lua["message"] = "Hello from C++";

// 执行 Lua 代码
lua.script(R"(
    print(x + y)
    print(message)
    print(x * y)
)");

在 Lua 中调用 C++ 函数

// C++ 函数
int add(int a, int b) {
    return a + b;
}

std::string greet(const std::string& name) {
    return "Hello, " + name + "!";
}

void print_vector(const std::vector<int>& v) {
    for (int x : v) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
}

int main() {
    sol::state lua;

    // 注册 C++ 函数到 Lua
    lua["add"] = add;
    lua["greet"] = greet;
    lua["print_vector"] = print_vector;

    // 在 Lua 中调用
    lua.script(R"(
        print(add(5, 3))
        print(greet("Lua"))
        print_vector({1, 2, 3, 4, 5})
    )");

    return 0;
}

从 C++ 创建 Lua 表

sol::state lua;

// 创建表
sol::table config = lua.create_table();
config["width"] = 1920;
config["height"] = 1080;
config["fullscreen"] = true;

// 创建嵌套表
config["display"] = lua.create_table_with(
    "brightness", 0.8,
    "contrast", 1.2
);

// 在 Lua 中访问
lua.script(R"(
    print(config.width)
    print(config.height)
    print(config.display.brightness)
)");

从 Lua 获取复杂数据

lua.script(R"(
    player = {
        name = "John",
        level = 25,
        inventory = {"sword", "shield", "potion"}
    }
)");

// 获取表
sol::table player = lua["player"];
std::string name = player["name"];
int level = player["level"];

// 获取数组
std::vector<std::string> inventory = player["inventory"];

std::cout << "Name: " << name << ", Level: " << level << std::endl;
for (const auto& item : inventory) {
    std::cout << "Item: " << item << std::endl;
}

C++ 类绑定到 Lua

#include <iostream>
#include <string>
#include "sol.hpp"

// C++ 类
class Player {
private:
    std::string name_;
    int health_;

public:
    Player(const std::string& name, int health)
        : name_(name), health_(health) {}

    void attack(int damage) {
        std::cout << name_ << " attacks for " << damage << " damage!" << std::endl;
    }

    void heal(int amount) {
        health_ += amount;
        std::cout << name_ << " heals for " << amount << " HP!" << std::endl;
    }

    std::string getName() const { return name_; }
    int getHealth() const { return health_; }
};

int main() {
    sol::state lua;

    // 绑定类到 Lua
    lua.new_usertype<Player>("Player",
        // 构造函数
        sol::constructors<Player(const std::string&, int)>(),
        // 属性
        "name", &Player::getName,
        "health", &Player::getHealth,
        // 方法
        "attack", &Player::attack,
        "heal", &Player::heal
    );

    // 在 Lua 中使用
    lua.script(R"(
        local player = Player.new("Hero", 100)
        print(player.name)
        print("Health:", player.health)
        
        player:attack(25)
        player:heal(10)
    )");

    return 0;
}

使用 Lua 表作为配置

// 加载配置文件
lua.script_file("config.lua");

// 读取配置
std::string server = lua["config"]["server"];
int port = lua["config"]["port"];
bool debug = lua["config"]["debug"];

std::cout << "Server: " << server << ":" << port << std::endl;
std::cout << "Debug: " << (debug ? "on" : "off") << std::endl;

/*
-- config.lua 内容
config = {
    server = "localhost",
    port = 8080,
    debug = true,
    log_file = "app.log"
}
*/

调用 Lua 脚本文件

lua.script_file("game_logic.lua");

// 脚本中定义的函数
auto initGame = lua["initGame"];
auto updateGame = lua["updateGame"];
auto processInput = lua["processInput"];

// 调用 Lua 函数
initGame();
updateGame(0.016f);  // delta time
processInput("W", "up");

/* 
-- game_logic.lua 内容
function initGame()
    print("Game initialized!")
end

function updateGame(dt)
    print("Update: " .. dt)
end

function processInput(key, action)
    print("Key: " .. key .. ", Action: " .. action)
end
*/

异常处理

sol::state lua;

// 捕获 Lua 错误
try {
    lua.script("this is invalid lua code");
} catch (sol::error& e) {
    std::cerr << "Lua 错误: " << e.what() << std::endl;
}

// 安全执行
auto result = lua.safe_script("return 1 + 1");
if (result.valid()) {
    std::cout << "结果: " << result.get<int>() << std::endl;
} else {
    sol::error err = result;
    std::cerr << "执行失败: " << err.what() << std::endl;
}

🎯 sol2 主要特性

📚 更多资源