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

MoonSharp 文档二

目录

6.Sharing objects(共享对象)

我们先来简单谈谈类型描述符

先说类型描述

稍微复杂一点

调用静态成员

应该使用 “:” 还是 “.”

重载

ByRef 参数(C# 中的 ref/out)

索引器

userdata 上的运算符和元方法

扩展方法

事件

关于 InteropAccessMode 的说明

更改可见性:使用 MoonSharpHidden 和 MoonSharpVisible

移除成员


MoonSharp 文档一-CSDN博客

MoonSharp 文档三-CSDN博客

MoonSharp 文档四-CSDN博客

MoonSharp 文档五-CSDN博客

6.Sharing objects(共享对象)

让 Lua 和 C# 互相交流。

文档地址:MoonSharp

备注:本页面中列出的某些特性反映了主分支的当前状态(因此,可能有一些特性在最新版本中缺失)。

MoonSharp 的一个方便特性是能够与脚本共享.NET对象。

默认情况下,一个类型会将其所有的公共方法、公共属性、公共事件和公共字段与Lua脚本共享。可以使用 MoonSharpVisible 特性来覆盖这个默认可见性。

建议使用专用对象作为 CLR 代码和脚本代码之间的接口(而不是将应用程序内部模型暴露给脚本)。许多设计模式(适配器、外观、代理等)可以帮助设计这样一个接口层。这对于以下方面尤其重要:

• 限制脚本可以做什么和不可以做什么(安全性!你想让你的模组作者找到一种方法来删除最终用户的个人文件吗?)

• 为脚本作者提供一个有意义的接口

• 分别记录接口

• 允许内部逻辑和模型在不破坏脚本的情况下进行更改

由于这些原因,MoonSharp 默认需要明确注册将提供给脚本的类型。

如果你处于脚本可以被信任的场景,你可以使用 UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic; 全局启用自动注册。这很危险,你已经被警告过了。

那么,让我们看看菜单上有什么:

• 首先让我们谈谈类型描述符] - 解释幕后发生的事情以及如何覆盖整个互操作系统的一点理论

• 保持简单 - 入门的最简单方法

• 稍微复杂一点 - 我们深入研究,增加一点复杂性和细节

• 调用静态成员 - 如何调用静态成员

• 应该使用':'还是'.'? - 关于如何调用方法的简单问题

• 重载 - 如何处理重载

• ByRef 参数(C# 中的 ref/out) - 如何处理 ref/out 参数

• 索引器 - 如何处理索引器

• userdata 上的运算符和元方法 - 如何重载运算符等

• 扩展方法 - 如何使用扩展方法

• 事件 - 如何使用事件

• 互操作访问模式 - 什么是互操作访问模式以及它如何工作

• 使用 MoonSharpHidden 和 MoonSharpVisible 更改可见性 - 如何覆盖成员的可见性

• 删除成员 - 如何删除成员的可见性

很多内容,让我们开始吧。

我们先来简单谈谈类型描述符

首先是一些关于互操作如何实现的小理论。每个 CLR 类型都被包装到一个"类型描述符"中,它的作用是向脚本描述 CLR 类型。为互操作注册一个类型意味着将类型与描述符(MoonSharp 可以自己创建)关联起来,描述符将用于调度方法、属性等。

从下一节开始,我们将参考 MoonSharp 提供的"自动"描述符,但你可以实现自己的描述符来提高速度、添加功能、增强安全性等。

如果你想实现自己的描述符(这并不容易,除非你需要,否则不应该这样做),你可以遵循以下路径:

• 创建一个特定的 IUserDataDescriptor 来描述你自己的类型 - 这是最困难的方式。

• 让你的类型实现 IUserDataType 接口。这更容易,但意味着你无法在没有对象实例的情况下处理静态成员。

• 扩展或嵌入 StandardUserDataDescriptor,并在保持其余行为的同时更改你需要的方面。

为了帮助创建描述符,提供了以下类:

• StandardUserDataDescriptor - 这是 MoonSharp 实现的类型描述符 •

• StandardUserDataMethodDescriptor - 这是单个方法/函数的描述符。

• StandardUserDataOverloadedMethodDescriptor - 这是重载和/或扩展方法的描述符。

• StandardUserDataPropertyDescriptor - 这是单个属性的描述符。

• StandardUserDataFieldDescriptor - 这是单个字段的描述符。

关于将值类型作为 userdata 进行互操作的一个小注意事项。

就像调用函数时将值类型作为参数传递一样,脚本将对用户数据的副本进行操作,因此,例如更改用户数据中的字段不会反映在原始值上。同样,这与值类型的标准行为没有任何不同,但足以让人感到惊讶。

此外,值类型不支持引用类型所具有的全部优化范围,因此某些操作在值类型上可能比在引用类型上更慢。

先说类型描述

好的,来看第一个例子。

[MoonSharpUserData]
class MyClass
{
	public double calcHypotenuse(double a, double b)
	{
		return Math.Sqrt(a * a + b * b);
	}
}

double CallMyClass1()
{
	string scriptCode = @"    
		return obj.calcHypotenuse(3, 4);
	";

	// Automatically register all MoonSharpUserData types
	UserData.RegisterAssembly();

	Script script = new Script();

	// Pass an instance of MyClass to the script in a global
	script.Globals["obj"] = new MyClass();

	DynValue res = script.DoString(scriptCode);

	return res.Number;
}

这里我们:

• 使用 [MoonSharpUserData] 属性定义了一个类
• 在脚本中将一个 MyClass 对象实例作为全局变量传递
• 从脚本中调用了 MyClass 的一个方法。所有回调的映射规则都适用

稍微复杂一点

让我们尝试一个更复杂的例子。

class MyClass
{
	public do

相关文章:

  • 蓝桥杯FPGA-ds1302驱动
  • 九点标定和十二点标定的区别
  • 【问题记录】如何编译nv_peer_memory模块?依赖OFED的4个目录和2类文件?如何解决没有rdma/peer_mem.h文件?
  • Python 远程抓取服务器日志最后 1000行
  • Vue3 路由的历史记录 如何不允许浏览器前进后退 在函数中使用路由切换组件 路由的重定向
  • 鸿基智启:东土科技为具身智能时代构建确定性底座
  • 英国赫瑞瓦特大学激光雷达领域研究概述2025.3.11
  • 计算机毕业设计:公寓管理系统
  • Ubuntu本地部署Open manus(完全免费可用)
  • 【OpenCV C++】存图,如何以时间命名,“年月日-时分秒“产生唯一的文件名呢?“年月日-时分秒-毫秒“ 自动检查存储目录,若不存在自动创建存图
  • FB投广探秘:为何Facebook广告账户不消耗
  • Unity安卓Android从StreamingAssets加载AssetBundle
  • Redis的高可用
  • 深入解析K8s VolumeMounts中的subPath字段及其应用
  • 怎么使用数据集微调大模型LLM
  • DeepSeek技术名词全解析:一场属于中国AI的“觉醒时刻”
  • Manus演示案例: 英伟达财务估值建模 解锁投资洞察的深度剖析
  • Trae IDE:解锁 AI 驱动的高效编程体验
  • 网络安全之RSA算法
  • 鸿道Intewell工业操作系统通过100%自主可控测评
  • 一周观展|一批重量级考古博物馆开馆:从凌家滩看到孙吴大墓
  • 体育文化赋能国际交流,上海黄浦举办国际友人城市定向赛
  • 摄影师|伊莎贝尔·穆尼奥斯:沿着身体进行文化溯源
  • 我使馆就中国公民和企业遭不公正待遇向菲方持续提出严正交涉
  • 既是工具又是食物,可食用机器人开启舌尖上的新科技
  • 普京调整俄陆军高层人事任命