当前位置: 首页 > news >正文

编程实战:类C语法的编译型脚本解释器(三)插件(自定义函数)接口

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


系列入口:

编程实战:类C语法的编译型脚本解释器(系列)-CSDN博客

        本文讲解插件(自定义函数)的接口。

        下文中的“插件”和“自定义函数”是两个概念:

  • “插件” 提供自定义函数功能的类,具有特殊的接口,一个插件实现一个自定义函数
  • “自定义函数” 脚本里的函数调用,形如“fun(a,b,c)”,脚本解释器负责将脚本里的函数调用与插件对应

目录

一、插件接口

二、插件管理器


一、插件接口

	//插件
	struct CPlugin
	{
		string plugin_name;
		Variable::types plugin_return_type;
		CPlugin() :plugin_name(""), plugin_return_type(Variable::NULLVARIABLE) {}
		CPlugin(char const* _name, Variable::types _type) :plugin_name(_name), plugin_return_type(_type) {}
		virtual string& help(string& ret)
		{
			ret = plugin_name + " : 返回值 " + Variable::TypeStr(plugin_return_type) + "\r\n";
			return ret;
		}
		virtual bool CheckPlugin(vector<Variable >& params, void*& pc, string& msg) = 0;
		virtual bool ExecFunction(vector<Variable >& params, void* const& pc, Variable& ret, string& msg, void* pe) = 0;
	};

        这是个关键的接口,只有两个成员变量:

类型名称说明
stringplugin_name自定义函数名称,也就是函数名
Variable::typesplugin_return_type自定义函数的返回值类型,返回值放在一个Variable中,必须明确指定返回类型,编译时会检查返回值类型是否正确

        两个构造函数无关紧要,只是提供了设置自定义函数名称和返回值类型而已。

        三个虚函数很重要:

  1. help() 返回自定义函数说明,已经提供了一个示例实现,这种参数传递方式是用来避免不必要的对象创建的。
  2. CheckPlugin() 编译时检查,如果返回false则编译不通过。后面详细介绍。
  3. ExecFunction() 执行,执行脚本时通过此接口获得返回值。 后面详细介绍。

        CheckPlugin()和ExecFunction()有很多共同的参数,一起介绍:

类型名称说明
vector<Variable>params函数的参数列表,也就是fun(a,b,c)的“a,b,c”,编译时提供的值是无意义的,但可以检查类型是否符合预期
void * &pc

编译时用户提供的指针的引用,用户可以在编译时修改,意即:用户可以在CheckPlugin里面申请内存,保存在pc变量里供执行时使用

此变量在执行时是只读的,但是指向的内容仍然是可以修改的(我感觉在运行时不断修改这个指针是难以理解的)(大BUG,这个值其实根本没设置,编译和运行都没有设置,没有这个参数

Variable &ret存放函数的返回值
string &msg如果执行出错,可以在这里放返回值
void *pe运行时由用户提供的指针

         CheckPlugin()和ExecFunction()本身的返回值为bool,表达插件本身执行成功或失败,具体区别借助实例来理解:

	struct CMax : public CPlugin
	{
		CMax() :CPlugin("max", Variable::DOUBLE) {}
		virtual string& help(string& ret)
		{
			ret = CPlugin::help(ret);
			ret += "取最大值,1-N个参数,参数必须是数值\r\n";
			return ret;
		}
		virtual bool CheckPlugin(vector<Variable >& params, void*& pc, string& msg)
		{
			msg = "";
			if (params.size() < 1)msg += "参数不足\r\n";
			for (size_t i = 0; i < params.size(); ++i)
			{
				if (!params[i].isNumber())msg += "参数必须是数值\r\n";
			}
			return 0 == msg.size();
		}
		virtual bool ExecFunction(vector<Variable >& params, void* const& pc, Variable& ret, string& msg, void* pe)
		{
			size_t _max = 0;
			for (size_t i = 1; i < params.size(); ++i)
			{
				if (params[i].GetDouble() > params[_max].GetDouble())_max = i;
			}
			ret = params[_max];
			return true;
		}
	};

        这是内置函数max的插件,CheckPlugin检查参数的个数和类型,ExecFunction则把参数转换为double然后把最大的放在ret中返回。

        这个插件没有用到pc和pe这两个参数,目前可以无视,因为这两个参数是客户代码使用的,插件解释器只是传递而并不操作,到需要用的时候你自然知道怎么用。 

二、插件管理器

	//插件表
	class CPluginMap
	{
	public:
		struct HANDLE
		{
			string plugin_name;

			bool isNULL()const { return 0 == plugin_name.size(); }
		};
	private:
		static map<string, CPlugin*>& GetPluginMap();
	public:
		template<typename T>
		static void addplugin(map<string, CPlugin*>& mapPlugins);
		static bool AddPlugin(char const* name, Variable::types type, CPlugin* p);
		static CPlugin* GetPlugin(string const& fun_name);
		static CPlugin* GetPlugin(HANDLE const& h);
		static string& PluginHelp(string& ret);
	};

        插件管理器管理所有的插件,也就是管理所有的自定义函数。

        子类型HANDLE是内部使用的,提供类似指针的快速访问,不过目前并没有性能优势,因为内部藏的还是自定义函数名。

        addPlugin往插件管理器里面添加插件,是静态方法。插件管理器的实现相当简单,也很随意,所以就不展开解释了。

        用户代码只需要在执行脚本前用addPlugin或AddPlugin添加插件即可。


(这里是结束,但是不是整个系列的结束)

相关文章:

  • 分享10个国内可以使用的GPT中文网站
  • Spring中的三级缓存和循环依赖
  • 玩转盲盒潮流:从0到1搭建小程序平台
  • “高考钉子户”唐尚珺决定再战2024年高考
  • 安装错误提示Please run MaterialLibrary2018.msi first或者其他MaterialLibrary版本
  • PostgreSQL用户与角色简述
  • 键盘盲打是练出来的
  • 状压dp 例题
  • 深入C++:深拷贝VS浅拷贝,编程高手必懂的技巧与陷阱
  • Spring Cloud 之 Gateway
  • 缪尔赛思又来到了你的面前(哈希)
  • 三台泵恒压供水站电控系统及PLC程序设计实例
  • 每日5题Day9 - LeetCode 41 - 45
  • git 查看远程分支地址
  • WordPress 发布了独立的 SQLite 插件
  • 阿里云oss存储直传回调服务的内网穿透
  • static的了解
  • 软件即服务-SaaS
  • 20.有序性与内存屏障
  • 设计模式14——组合模式
  • 上海科创的三种品格
  • 卸任兰大校长后,严纯华院士重返北大作报告
  • 今年我国电影票房破250亿领跑全球,“电影+”带动文旅消费热潮
  • 新版国家卫生监督抽查计划发布,首次明确打击网络“医托”
  • 永辉超市一季度净利降近八成,未来12个月至18个月是改革成果集中释放期
  • 博物馆有一项活动40岁以上不能参加?馆方回应