关于yasio的Lua绑定思考

最近,将 yasio Lua 绑定集成到xlua中使用,结果发现在Apple clang release优化编译模式下,lua构造yasio的io_service对象是直接crash了,刚开始表现是Unity Editor预览即闪退,后通过Xcode附加+VS联合调试发现crash原因是Bad Access, 于是花时间研究了下,将yasio从之前只能在c++11标准下编译,到现在支持在c++14,c++17乃至c++20标准下编译,同时对问题做了如下总结:

  • c++11:

    • 使用kaguya绑定库,但这个库有个问题:在绑定c++类的过程中,构造c++对象过程是先通过lua_newuserdata, 再通过placement new构造对象,在xcode clang release优化编译下会直接闪退
    • 经过bing.com搜索,发现可通过定义LUAI_USER_ALIGNMENT_T=max_align_t来解决
    • 经过测试, max_align_t在xcode clang下定义为long double类型,长度为16个字节
    • 参考: http://lua-users.org/lists/lua-l/2019-07/msg00197.html
  • c++14:

    • 使用sol2绑定库,sol2可以成功解决kaguya的问题,经过查看sol2的源码,发现其在内部对lua_newuserdata返回的地址做了对齐处理,因此成功避免了clang release优化地址不对齐闪退问题
  • c++17:

    • 同样使用sol2库,但xcode会提示ios11以下不支持C++17默认new操作符的Aligned allocation/deallocation,通过添加编译选项-faligned-allocation可通过编译;
    • ios10以下不支持stl的shared_mutex(yasio最近做了兼容,对于Apple平台一律使用pthread实现)
  • 本人思考和结论(欢迎指正):

    • Lua虚拟机实现中默认最大对齐类型是double,而max_align_t类型是C11标准才引入的: max_align_t ,因此Lua作为ANSI C89标准兼容实现并未完美处理各个编译器地址对齐问题,而是留给了用户定义: LUAI_USER_ALIGNMENT_T
    • 在C++11编译系统下已经引入 std::max_align_t类型,而通常我们移动平台开发早已使用C++11标准,因此接入Lua支持时,应当始终将LUAI_USER_ALIGNMENT_T定义为max_align_t,以确保lua_newuserdata始终能够返回地址对齐的内存

猜你喜欢

转载自blog.csdn.net/xyzzf/article/details/106043674