一种魔性的C++内嵌脚本的方式

2021-10-29 15:32:41 浏览数 (1)

一种魔性的C 内嵌脚本的方式

最近在处理框架代码脚本模块的封装, 然后有一些系统级的脚本想内嵌, 又没找到特别合适的方法, 直到看到hive-framework的代码:

代码语言:javascript复制
static const char* g_sandbox = u8R"__(
hive.files = {};
hive.meta = {__index=function(t, k) return _G[k]; end};
hive.print = function(...) end; --do nothing

-- some ignore codes here

)__";

通过C 11的RawString, 已经比原来"n"到处飞的情况好太多了, 那么如果我希望在IDE里很正常的对Lua代码进行编辑, 有没有办法呢? 答案是肯定的.

我们使用的方式

示例代码如下所示:

代码语言:javascript复制
R"__"--(--this start line is need for embeded script

rstudio = {}
rstudio.files = {};
rstudio.meta = {__index=function(t, k) return _G[k]; end};

-- some codes ignore here

function import_folder(filename)
    return ImportImpl(filename, true)
end

--this end line is need for embeded script)__"--"

估计大家也注意到代码段前面和后面的两行代码了:

代码语言:javascript复制
R"__"--(--this start line is need for embeded script
--this end line is need for embeded script)__"--"

这里其实是C 11的Raw String, 然后目前我们使用了一个比较特殊的方法, 可以比较好的处理内嵌代码, 首先是文件头部和文件尾部如上面代码段所示的两行, C 的Raw String是以"(" 和 ")"作为起始符和结束符的, 第一个"("前的内容和最后一个")"后的内容都会被忽略, 通过略魔性的这两行, 我们即完成了一个C 标准Raw String的声明, 也能够保证Lua代码在IDE中的可编辑性(不会被整体识别成一个字符串). 实际的内嵌使用如下图所示:

代码语言:javascript复制
namespace rstudio
{
    namespace embed_script
    {
        const std::string g_base_class_lua_source = (const char*) 
#include "lua_script_system/embed_source/lua/baseclass.lua"
;
        const std::string g_scheduler_lua_source = (const char*)
#include "lua_script_system/embed_source/lua/scheduler.lua"
;
        const std::string g_module_sandbox_lua_source = (const char*)
#include "lua_script_system/embed_source/lua/module_sandbox.lua"
;
    }
}

略魔性, 但确实可以比较好的解决内嵌脚本代码的问题, 所以这里额外展开说明一下. 这样我们就能简单的通过 g_base_class_lua_source变量访问到内嵌的lua代码了, 比最原始的方式或者hive的方式应该是更友好的.

结语

题外话, 个人感觉hive-framework的模块代码真的比较赞, 核心不到100行, 相当的简短, 但对于实际使用来说, 提供了支持对比文件修改时间Reload, 模块的Sandbox特性(隔离性), 还是相当优雅的.

0 人点赞