使用sol库传递C++结构体PriceData到Lua时出错,求解决方法
问题分析与解决
核心问题
你遇到的错误根源有两个:
- 结构体构造函数不匹配:代码中用
PriceData pd(106.0, 107.0);初始化对象,但给出的PriceData是聚合类型,没有接受两个double参数的构造函数;同时sol2注册时指定的拷贝构造函数签名写法有误。 - sol2用户类型注册不正确:错误的构造函数注册导致sol2无法将C++的
PriceData对象正确转换为Lua能识别的userdata类型,触发参数类型不匹配错误。
修复步骤
1. 修正PriceData结构体定义
添加必要的构造函数,确保初始化和sol2识别正常:
struct PriceData { double best_bid = 0.0; double best_ask = 0.0; // 默认构造(显式声明更清晰,聚合类型也会默认生成) PriceData() = default; // 双参数构造,支持直接用bid/ask值初始化 PriceData(double bid, double ask) : best_bid(bid), best_ask(ask) {} // 拷贝构造(默认生成,显式声明可选) PriceData(const PriceData&) = default; }; inline bool operator == (const PriceData& lhs, const PriceData& rhs) { return lhs.best_bid == rhs.best_bid && lhs.best_ask == rhs.best_ask; }
2. 修正sol2用户类型注册
调整构造函数的注册签名,匹配结构体实际的构造函数:
sol::state _interpreter; _interpreter.open_libraries(sol::lib::base, sol::lib::math); _interpreter.new_usertype<PriceData>( "PriceData", // 注册所有可用的构造函数,让Lua可以灵活创建对象 sol::constructors<PriceData(), PriceData(double, double), PriceData(const PriceData&)>(), "best_bid", &PriceData::best_bid, "best_ask", &PriceData::best_ask ); std::string script = R"( function check_condition(price_update) -- 打印具体属性,而不是直接打印userdata对象 print("best_bid:", price_update.best_bid, "best_ask:", price_update.best_ask) return true end )"; auto load_result = _interpreter.load(script); if (!load_result.valid()) throw std::runtime_error(std::format("Failed to load condition inspector. Error: {}", sol::error{load_result}.what())); auto f = load_result.get<sol::function>(); PriceData pd(106.0, 107.0); // 调用函数时,sol2会自动将C++对象包装为Lua userdata f(pd);
3. 额外优化
脚本中直接print(price_update)只会输出userdata的内存地址,改为打印具体属性可以更直观验证数据是否正确传递。
报错原因说明
你注册的构造函数PriceData(PriceData pd)是值传递的拷贝构造,而sol2更推荐使用const引用的签名PriceData(const PriceData&);同时缺少双参数构造函数会导致初始化对象时的潜在问题,双重因素叠加导致sol2无法正确识别并转换C++对象为Lua userdata,最终触发参数类型错误。
内容的提问来源于stack exchange,提问作者Timur Yalymov
相关产品推荐
相关产品推荐

