MoonSharp 文档二
目录
6.Sharing objects
我们先来简单谈谈类型描述符
先说类型描述
稍微复杂一点
调用静态成员
应该使用 “:” 还是 “.”
重载
ByRef 参数(C# 中的 ref/out)
索引器
userdata 上的运算符和元方法
扩展方法
事件
关于 InteropAccessMode 的说明
更改可见性:使用 MoonSharpHidden 和 MoonSharpVisible
移除成员
官方链接:
MoonSharp
6.Sharing objects
让 Lua 和 C# 互相交流。
备注:本页面中列出的某些特性反映了主分支的当前状态(因此,可能有一些特性在最新版本中缺失)。
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 typesUserData.RegisterAssembly();Script script = new Script();// Pass an instance of MyClass to the script in a globalscript.Globals["obj"] = new MyClass();DynValue res = script.DoString(scriptCode);return res.Number;
}
这里我们:
• 使用 [MoonSharpUserData] 属性定义了一个类
• 在脚本中将一个 MyClass 对象实例作为全局变量传递
• 从脚本中调用了 MyClass 的一个方法。所有回调的映射规则都适用
稍微复杂一点
让我们尝试一个更复杂的例子。
class MyClass
{public double CalcHypotenuse(double a, double b){return Math.Sqrt(a * a + b * b);}
}static double CallMyClass2()
{string scriptCode = @" return obj.calcHypotenuse(3, 4);";// Register just MyClass, explicitely.UserData.RegisterType<MyClass>();Script script = new Script();// create a userdata, again, explicitely.DynValue obj = UserData.Create(new MyClass());script.Globals.Set("obj", obj);DynValue res = script.DoString(scriptCode);return res.Number;
}
这里的主要区别在于:
• 没有使用 [MoonSharpUserData] 属性。我们不再需要它了。
• 我们调用 RegisterType 来注册一个特定类型,而不是使用 RegisterAssembly。
• 我们显式地创建了 userdata DynValue。
• 另外,请注意在 C# 代码中方法名为 CalcHypotenuse,但在 Lua 脚本中被调用为 calcHypotenuse。
只要其他版本不存在,MoonSharp 会以一些有限的方式自动调整大小写以匹配成员,以更好地适应不同语言语法约定。例如,一个名为 SomeMethodWithLongName 的成员也可以在 Lua 脚本中被访问为 someMethodWithLongName 或 some_method_with_long_name。
调用静态成员
假设我们的类中有一个静态方法 calcHypotenuse。
[MoonSharpUserData]
class MyClassStatic
{public static double calcHypotenuse(double a, double b){return Math.Sqrt(a * a + b * b);}
}
我们可以用两种方式调用它。
第一种方式 - 静态方法可以透明地从一个实例中调用 - 无需做任何操作,一切都是自动的。
double MyClassStaticThroughInstance()
{string scriptCode = @" return obj.calcHypotenuse(3, 4);";// Automatically register all MoonSharpUserData typesUserData.RegisterAssembly();Script script = new Script();script.Globals["obj"] = new MyClassStatic();DynValue res = script.DoString(scriptCode);return res.Number;
}
另一种方式 - 可以通过直接传递类型(或使用 UserData.CreateStatic 方法)创建一个占位符用户数据:
double MyClassStaticThroughPlaceholder()
{string scriptCode = @" return obj.calcHypotenuse(3, 4);";// Automatically register all MoonSharpUserData typesUserData.RegisterAssembly();Script script = new Script();script.Globals["obj"] = typeof(MyClassStatic);DynValue res = script.DoString(scriptCode);return res.Number;
}
应该使用 “:” 还是 “.”
考虑到上述例子中的代码,一个很好的问题是,是否应该使用这种语法。
return obj.calcHypotenuse(3, 4);
或者:
return obj:calcHypotenuse(3, 4);
99.999% 的情况下,这没有任何区别。MoonSharp 知道正在对一个 userdata 进行调用,并会相应地处理。
有些极端情况可能会有所不同,比如如果一个属性返回一个委托,并且你打算立即调用那个委托,以原始对象作为实例。这是一个较少见的情景,当这种情况发生时,你需要手动处理。
重载
重载方法是支持的。重载方法的分派有些神奇,不像C#重载分派那样确定。这是因为存在一些歧义。例如,一个对象可以声明这两个方法:
void DoSomething(int i) { ... }
void DoSomething(float f) { ... }
如何让 MoonSharp 知道在 Lua 中所有数字都是双精度类型的情况下,应该调用哪个方法?
为解决这个问题,MoonSharp 根据输入类型为所有重载计算出一个启发式因子,并选择最佳重载。如果你认为 MoonSharp 在解析重载时出现了错误,请向论坛或 Discord 报告,以便对启发式进行校准。
MoonSharp 尽可能保持启发式权重的稳定性,并且在方法之间的得分出现平局时,它总是以确定的方式选择相同的一个(以提供在不同构建和平台之间一致的体验)。
话虽如此,MoonSharp 选择的重载可能与你想的不同。因此,极其重要的是重载执行等效的任务,以便将调用错误重载的影响降到最低。这本应是一个最佳实践,但在这里强化这一概念是值得的。
ByRef 参数(C# 中的 ref/out)
ByRef 方法参数通过 MoonSharp 作为多个返回值正确地进行了封送处理。这种支持并非没有副作用,因为带有 ByRef 参数的方法无法进行优化。
假设我们有这样一个 C# 方法(为了论证起见,暴露在一个名为 myobj 的 userdata 中)
public string ManipulateString(string input, ref string tobeconcat, out string lowercase)
{tobeconcat = input + tobeconcat;lowercase = input.ToLower();return input.ToUpper();
}
我们可以通过以下方式从 Lua 代码调用这个方法(并获取结果):
x, y, z = myobj:manipulateString('CiAo', 'hello');-- x will be "CIAO"
-- y will be "CiAohello"
-- z will be "ciao"
虽然支持,ByRef 参数会导致方法总是通过反射来调用,因此可能会在非 AOT 平台上降低性能(AOT 平台本来就慢... 抱怨请向苹果公司反映,不要找我)。
索引器
C# 允许创建索引器方法。例如:
class IndexerTestClass
{Dictionary<int, int> mymap = new Dictionary<int, int>();public int this[int idx]{get { return mymap[idx]; }set { mymap[idx] = value; }}public int this[int idx1, int idx2, int idx3]{get { int idx = (idx1 + idx2) * idx3; return mymap[idx]; }set { int idx = (idx1 + idx2) * idx3; mymap[idx] = value; }}
}
作为 Lua 语言的扩展,MoonSharp 允许在方括号内使用表达式列表来索引用户数据。例如,如果 o 是上述类的一个实例,那么以下代码行是有效的:
-- sets the value of an indexer
o[5] = 19; -- use the value of an indexer
x = 5 + o[5]; -- sets the value of an indexer using multiple indices (not standard Lua!)
o[1,2,3] = 19; -- use the value of an indexer using multiple indices (not standard Lua!)
x = 5 + o[1,2,3];
请注意,对非用户数据使用多个索引将引发错误。这包括通过元方法的场景,但如果元表的 __index 字段设置为用户数据(也可以是递归的),则支持多重索引。
简而言之,这是有效的:
m = { __index = o,__newindex = o
}t = { }setmetatable(t, m);t[10,11,12] = 1234; return t[10,11,12];";
并且这不会:
m = { -- we can't even write meaningful functions here, but let's pretend...__index = function(obj, idx) return o[idx] end, __newindex = function(obj, idx, val) end
}t = { }setmetatable(t, m);t[10,11,12] = 1234; return t[10,11,12];";
userdata 上的运算符和元方法
支持重载运算符。
以下是标准描述符如何分派运算符的说明,但你可以在此单元测试代码中看到工作示例。
显式元方法实现 首先,如果实现了一个或多个使用 MoonSharpUserDataMetamethod 修饰的静态方法,则使用这些方法来分派相应的元方法。请注意,如果这些方法存在,它们将优先于以下任何其他标准。
__pow、__concat、__call、__pairs 和 __ipairs 只能通过这种方式实现(除非使用自定义描述符)。
例如,以下代码将实现 concat (..) 运算符:
[MoonSharpUserDataMetamethod("__concat")]
public static int Concat(ArithmOperatorsTestClass o, int v)
{return o.Value + v;
}[MoonSharpUserDataMetamethod("__concat")]
public static int Concat(int v, ArithmOperatorsTestClass o)
{return o.Value + v;
}[MoonSharpUserDataMetamethod("__concat")]
public static int Concat(ArithmOperatorsTestClass o1, ArithmOperatorsTestClass o2)
{return o1.Value + o2.Value;
}
隐式元方法实现用于算术运算符
如果找到,算术运算符将通过运算符重载自动处理。
public static int operator +(ArithmOperatorsTestClass o, int v)
{return o.Value + v;
}public static int operator +(int v, ArithmOperatorsTestClass o)
{return o.Value + v;
}public static int operator +(ArithmOperatorsTestClass o1, ArithmOperatorsTestClass o2)
{return o1.Value + o2.Value;
}
这将可以在 Lua 脚本中对数字和此对象使用 + 运算符。
加法、减法、乘法、除法、取模和一元负运算符都以这种方式支持。
比较运算符、长度运算符和 __iterator 元方法
相等运算符(== 和 ~=)使用 System.Object.Equals 自动解析。
如果对象实现了 IComparable,则使用 IComparable.CompareTo 自动解析比较运算符(<、>= 等)。
如果对象实现了 Length 或 Count 属性,则长度 (#) 运算符将分派到这些属性。
最后,如果类实现了 System.Collections.IEnumerable,则 __iterator 元方法会自动分派到 GetEnumerator。
扩展方法
支持扩展方法。
扩展方法必须使用 UserData.RegisterExtensionType 或通过 RegisterAssembly(<assembly>, true) 进行注册。前者将注册一个包含扩展方法的单一类型,后者注册指定程序集中包含的所有扩展类型。
扩展方法与其他方法重载一起解析。
事件
也支持事件,但方式相当简约。只支持符合以下约束的事件:
事件必须在引用类型中声明
事件必须同时实现 add 和 remove 方法
事件处理程序的返回类型必须是 System.Void(在 VB.NET 中必须是 Sub)
事件处理程序必须有 16 个或更少的参数
事件处理程序不能有值类型参数或按引用传递的参数
事件处理程序签名不能包含指针或未解析的泛型
事件处理程序的所有参数必须可转换为 MoonSharp 类型
这些约束的目的是尽可能避免在运行时构建代码。
虽然它们可能看起来有限制,但在大多数情况下,它们实际上反映了事件设计中的一些最佳实践;它们足以支持 EventHandler 和 EventHandler<T> 类型的事件处理程序,而这些是目前最常见的(前提是至少将 EventArgs 注册为用户数据)。
下面是一个使用事件的简单示例:
class MyClass
{public event EventHandler SomethingHappened;public void RaiseTheEvent(){if (SomethingHappened != null)SomethingHappened(this, EventArgs.Empty);}
}static void Events()
{string scriptCode = @" function handler(o, a)print('handled!', o, a);endmyobj.somethingHappened.add(handler);myobj.raiseTheEvent();myobj.somethingHappened.remove(handler);myobj.raiseTheEvent();";UserData.RegisterType<EventArgs>();UserData.RegisterType<MyClass>();Script script = new Script();script.Globals["myobj"] = new MyClass();script.DoString(scriptCode);
}
请注意这一次事件是由 Lua 代码触发的,但它也可能由 C# 触发,不会有任何问题。
添加和移除事件处理程序是缓慢的操作,它们是在一个线程锁下使用反射执行的。另一方面,处理事件本身并没有很大的性能损失。
关于 InteropAccessMode 的说明
如果你在 IDE 中输入了所有到目前为止的示例,你可能已经注意到大多数方法都有一个可选的 InteropAccessMode 类型参数。
InteropAccessMode 定义了标准描述符如何处理对 CLR 事物的回调。可用的值包括:
有一个 UserData.DefaultAccessMode 静态属性用来指定哪个值应被视为默认值(当前是 LazyOptimized,除非进行更改)。
Reflection | Optimization is not performed and reflection is used everytime to access members. This is the slowest approach but saves a lot of memory if members are seldomly used. 翻译:没有进行优化,每次访问成员时都使用反射。这是最慢的方法,但如果很少使用成员,则可以节省大量内存。 |
---|---|
LazyOptimized | This is a hint, and MoonSharp is free to "downgrade" this to Reflection . Optimization is done on the fly the first time a member is accessed. This saves memory for all members that are never accessed, at the cost of an increased script execution time.翻译:这是一个提示,MoonSharp 可以自由地将其“降级”到反射。第一次访问成员时进行即时优化。这样可以为从未访问过的所有成员节省内存,但代价是增加了脚本执行时间。 |
Preoptimized | This is a hint, and MoonSharp is free to "downgrade" this to Reflection . Optimization is done in a background thread which starts at registration time. If a member is accessed before optimization is completed, reflection is used.翻译:这是一个提示,MoonSharp 可以自由地将其“降级”到反射。优化在注册时开始的后台线程中执行。如果在优化完成之前访问了成员,则使用反射。 |
BackgroundOptimized | This is a hint, and MoonSharp is free to "downgrade" this to Reflection . Optimization is done at registration time.翻译:这是一个提示,MoonSharp可以自由地将其"降级"到反射。优化是在注册时完成的。 |
HideMembers | Members are simply not accessible at all. Can be useful if you need a userdata type whose members are hidden from scripts but can still be passed around to other functions. See also AnonWrapper and AnonWrapper<T> .翻译:成员完全不可访问。如果您需要一个用户数据类型,其成员对脚本是隐藏的,但仍然可以传递给其他函数,这可能很有用。另请参阅AnonWrapper和AnonWrapper<T>。 |
Default | Use the default access mode 翻译:使用默认的访问模式。 |
请注意,许多模式 - 特别是 LazyOptimized、Preoptimized 和 BackgroundOptimized - 只是"提示",MoonSharp 可以自由地将它们降级为 Reflection。例如,在代码提前编译的平台(如iPhone和iPad)上就会发生这种情况。
更改可见性:使用 MoonSharpHidden 和 MoonSharpVisible
可以使用 MoonSharpHidden 和/或 MoonSharpVisible 属性来覆盖成员的默认可见性(MoonSharpHidden 是 MoonSharpVisible(false) 的快捷方式)。以下是一些带有注释的示例——并不复杂:
public class SampleClass
{// Not visible - it's privateprivate void Method1() { }// Visible - it's publicpublic void Method2() { }// Visible - it's private but forced visible by attribute[MoonSharpVisible(true)]private void Method3() { }// Not visible - it's public but forced hidden by attribute[MoonSharpVisible(false)]public void Method4() { }// Not visible - it's public but forced hidden by attribute[MoonSharpHidden]public void Method4() { }// Not visible - it's privateprivate int Field1 = 0;// Visible - it's publicpublic int Field2 = 0;// Visible - it's private but forced visible by attribute[MoonSharpVisible(true)]private int Field3 = 0;// Not visible - it's public but forced hidden by attribute[MoonSharpVisible(false)]public int Field4 = 0;// Not visible at all - it's privateprivate int Property1 { get; set; }// Read/write - it's publicpublic int Property2 { get; set; }// Readonly - it's public, but the setter is privatepublic int Property3 { get; private set; }// Write only! - the MoonSharpVisible makes the getter hidden and the setter visible!public int Property4 { [MoonSharpVisible(false)] get; [MoonSharpVisible(true)] private set; }// Write only! - the MoonSharpVisible makes the whole property hidden but another attribute resets the setter as visible![MoonSharpVisible(false)]public int Property5 { get; [MoonSharpVisible(true)] private set; }// Not visible at all - the MoonSharpVisible hides everything[MoonSharpVisible(false)]public int Property6 { get; set; }// Not visible - it's privateprivate event EventHandler Event1;// Visible - it's publicpublic event EventHandler Event2;// Visible - it's private but forced visible by attribute[MoonSharpVisible(true)]private event EventHandler Event3;// Not visible - it's public but forced hidden by attribute[MoonSharpVisible(false)]public event EventHandler Event4;// Not visible - visibility modifiers over add and remove are not currently supported![MoonSharpVisible(false)]public event EventHandler Event5 { [MoonSharpVisible(true)] add { } [MoonSharpVisible(true)] remove { } } }
移除成员
有时需要从已注册的类型中移除成员,以便在脚本中隐藏它们。有几种方法可以做到这一点。其中一种方法是在类型注册后手动移除它们:
var descr = ((StandardUserDataDescriptor)(UserData.RegisterType<SomeType>()));
descr.RemoveMember("SomeMember");
或者,只需将此属性添加到类型声明中:
[MoonSharpHide("SomeMember")]
public class SomeType
...
这是非常重要的,因为你可能希望隐藏某些你没有重写的继承成员。
end
相关文章:

MoonSharp 文档二
目录 6.Sharing objects 我们先来简单谈谈类型描述符 先说类型描述 稍微复杂一点 调用静态成员 应该使用 “:” 还是 “.” 重载 ByRef 参数(C# 中的 ref/out) 索引器 userdata 上的运算符和元方法 扩展方法 事件 关于 InteropAccessMode 的…...

android 支持自定义布局、线程安全、避免内存泄漏的 Toast 工具类
支持自定义布局:可以灵活地显示自定义样式的 Toast。 线程安全:确保在主线程中显示 Toast,避免崩溃。 避免内存泄漏:使用 ApplicationContext 和取消机制,防止内存泄漏问题。 工具类:作为一个通用的工具…...

景联文科技:以精准数据标注赋能AI进化,构筑智能时代数据基石
在人工智能技术席卷全球的浪潮中,高质量数据已成为驱动AI模型进化的核心燃料。作为全球领先的AI数据服务解决方案提供商,景联文科技深耕数据标注领域多年,以技术为基、以专业为本,致力于为全球客户提供全场景、高精度、多模态的数…...

Mysql的卸载安装配置以及简单使用
MySQL其它问题已经更新在:MySQL完善配置---可视化-CSDN博客 一、卸载 ①控制面板卸载 ②C盘隐藏项目>ProgramData>mysql相关文件夹,还有Program file下的MySQL文件夹 ③开始菜单栏搜索>服务,找到MySQL相关服务删除,如果再…...

使用 ResponseBodyEmitter 实现异步响应式数据流处理
1. 概述 1.1 什么是 ResponseBodyEmitter ResponseBodyEmitter 是 Spring MVC 提供的一个接口,用于支持异步返回响应数据流。它允许在控制器方法中逐步发送数据给客户端,而无需一次性生成完整的响应。 1.2 使用场景 实时数据推送(如股票行情、聊天消息等)。大量数据分批…...

Uniapp项目运行到微信小程序、H5、APP等多个平台教程
摘要:Uniapp作为一款基于Vue.js的跨平台开发框架,支持“一次开发,多端部署”。本文将手把手教你如何将Uniapp项目运行到微信小程序、H5、APP等多个平台,并解析常见问题。 一、环境准备 在开始前,请确保已安装以下工具…...

Ubuntu 下 nginx-1.24.0 源码分析 - cycle->modules[i]->type
Nginx 中主要有以下几种模块类型 类型 含义 NGX_CORE_MODULE 核心模块(如进程管理、错误日志、配置解析)。 NGX_EVENT_MODULE 事件模块(如 epoll、kqueue 等 IO 多路复用机制的实现)。 NGX_HTTP_MODULE HTTP 模块…...

基于SpringBoot的“文物管理系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“文物管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体功能模块图 E-R实体图 系统首页界面 系统…...

dify + ollama + deepseek-r1+ stable-diffusion 构建绘画智能体
故事背景 stable-diffusion 集成进 dify 后,我们搭建一个小智能体,验证下文生图功能 业务流程 #mermaid-svg-6nSwwp69eMizP6bt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6nSwwp69eMiz…...
Android原生gif动图加载AnimatedImageDrawable
Android原生gif动图加载AnimatedImageDrawable 从Android P(9.0)开始,Android系统支持gif动图的原生控件AnimatedImageDrawable,可以播放加载gif动图。 AnimatedImageDrawable官方文档链接: https://developer.andro…...

Windows 系统 Docker Desktop 入门教程:从零开始掌握容器化技术
文章目录 前言一、Docker 简介二、Docker Desktop 安装2.1 系统要求2.2 安装步骤 三、Docker 基本概念四、Docker 常用命令五、实战:运行你的第一个容器5.1 拉取并运行 Nginx 容器5.2 查看容器日志5.3 停止并删除容器 六、总结 前言 随着云计算和微服务架构的普及&…...

记录小白使用 Cursor 开发第一个微信小程序(二):创建项目、编译、预览、发布(250308)
文章目录 记录小白使用 Cursor 开发第一个微信小程序(二):创建项目、编译、预览、发布(250308)一、创建项目1.1 生成提示词1.2 生成代码 二、编译预览2.1 导入项目2.2 编译预览 三、发布3.1 在微信开发者工具进行上传3…...

实战 - 使用 AutoAWQ 进行量化
文章目录 一、准备1、安装 autoawq2、模型准备 二、量化config.json 文件变化 三、加载量化后模型量化后的输出原始输出对比 四、查看模型的精度1、查看模型卡2、查看 config.json 中的 torch_dtype3、打印模型信息4、model.dtype 未必是模型精度 一、准备 1、安装 autoawq p…...

C++20 格式化库:强大的字符串格式化工具
文章目录 格式化语法常见用法1. 填充和对齐2. 数值格式化3. 进制格式化4. 自定义类型 示例代码注意事项 C20 的格式化库是一个强大的工具,用于处理字符串的格式化操作。它提供了类似于 Python 中 str.format() 的功能,但语法和用法更符合 C 的风格。以下…...

【一文学会 HTML5】
目录 HTML概述基本概念HTML 发展历程HTML 基本结构 网页基本标签标题标签(<h1> - <h6>)段落标签(<p>)换行标签(<br>)水平线标签(<hr>)注释࿰…...

如何在WPS中接入DeepSeek并使用OfficeAI助手(超细!成功版本)
目录 第一步:下载并安装OfficeAI助手 第二步:申请API Key 第三步:两种方式导入WPS 第一种:本地大模型Ollama 第二种APIKey接入 第四步:探索OfficeAI的创作功能 工作进展汇报 PPT大纲设计 第五步:我的使用体验(体验建议) …...

蓝耘智算 + 通义万相 2.1:为 AIGC 装上 “智能翅膀”,翱翔创作新天空
1. 引言:AIGC 的崛起与挑战 在过去几年中,人工智能生成内容(AIGC)技术突飞猛进。AIGC 涉及了文本生成、图像创作、音乐创作、视频制作等多个领域,并逐渐渗透到日常生活的方方面面。传统的内容创作方式已经被许多人类创…...

电脑如何在系统默认的壁纸中切换自己喜欢的
1、声明:该切换壁纸仅支持win10。 当你想去切换系统默认的壁纸,但是不知道该怎么切换,别慌,小亦教你几招帮你快速切换自定义壁纸。 我们平常使用的win10桌面壁纸大部分都是 简单、朴素的壁纸,但如果你想要切换自己喜…...

【大模型安全】安全解决方案
【大模型安全】安全解决方案 1.技术层面2.数据层面数据收集阶段训练阶段模型推理阶段 1.技术层面 在使用大语言模型时,通常有几种选择:一种是采用封装好的大语言模型SaaS云服务;另一种是在公有云上部署自有的大语言模型,并通过权…...

Windows编译环境搭建(MSYS2\MinGW\cmake)
我的音视频/流媒体开源项目(github) 一、基础环境搭建 1.1 MSYS2\MinGW 参考:1. 基于MSYS2的Mingw-w64 GCC搭建Windows下C开发环境_msys2使用mingw64编译 在Widndows系统上,使用gcc工具链(g)进行C程序开发?可以的&a…...

云曦春季开学考复现(2025)
Crypto 划水的dp和dq 下载附件后是简单的RSA算法题,之所以说简单是因为给了公钥e 趁热打铁,昨天刚学的RSA,既然有p有q,也有e,而np*q,可以算出欧拉函数值phi(p-1)*(q-1&…...

股票交易所官方api接口有哪些?获取和使用需要满足什么条件
炒股自动化:申请官方API接口,散户也可以 python炒股自动化(0),申请券商API接口 python炒股自动化(1),量化交易接口区别 Python炒股自动化(2):获取…...

《WebForms 实例》
《WebForms 实例》 引言 WebForms 是微软推出的一种用于构建动态Web应用程序的技术。它基于ASP.NET框架,允许开发者使用服务器端控件来构建用户界面,并通过事件驱动模型来响应用户交互。本文将通过一些实例,详细介绍WebForms的使用方法&…...

【每日学点HarmonyOS Next知识】 状态变量、公共Page、可见区域变化回调、接收参数、拖拽排序控件
1、HarmonyOS 在定时器里面改变state修饰的变量,无法更新UI吗? 将函数function写成了封装函数的形式就可以了 Entry Component struct Index {State acSetValve: number 0;aboutToAppear(): void {setInterval(() > {this.acSetValve 200;console…...

Intent3D
1. 研究背景 在现实世界中,人们寻找 3D 物体的行为往往基于特定意图,例如“我想要一个可以支撑我背部的东西”(即寻找枕头)。传统 3D 视觉定位(3D-VG)主要依赖人工提供的参照信息(如“沙发上的…...

【Python 数据结构 10.二叉树】
目录 一、二叉树的基本概念 1.二叉树的定义 2.二叉树的特点 3.特殊的二叉树 Ⅰ、斜树 Ⅱ、满二叉树 Ⅲ、完全二叉树 Ⅳ、完全二叉树和满二叉树的区别 4.二叉树的性质 5.二叉树的顺序存储 Ⅰ、完全二叉树 Ⅱ、非完全二叉树 Ⅲ、稀疏二叉树 6.二叉树的链式存储 7.二叉树的遍历概念…...

从0开始的操作系统手搓教程27:下一步,实现我们的用户进程
目录 第一步:添加用户进程虚拟空间 准备冲向我们的特权级3(用户特权级) 讨论下我们创建用户线程的基本步骤 更加详细的分析代码 用户进程的视图 说一说BSS段 继续看process.c中的函数 添加用户线程激活 现在,我们做好了TSS…...

set、LinkedHashSet和TreeSet的区别、Map接口常见方法、Collections 工具类使用
DAY7.2 Java核心基础 想学习Collection、list、ArrayList、Set、HashSet部分的小伙伴可以转到 7.1集合框架、Collection、list、ArrayList、Set、HashSet和LinkedHashSet、判断两个对象是否相等文章查看 set集合 在set集合中,处理LinkedHashSet是有序的…...

Qt开发:nativeEvent事件的使用
文章目录 一、概述二、nativeEvent 的定义三、Windows 平台示例三、使用nativeEvent监测设备变化 一、概述 Qt 的 nativeEvent 是一个特殊的事件处理机制,允许开发者处理操作系统级别的原生事件。通常,Qt 通过 QEvent 机制来管理事件,但有时…...

鸿蒙Next-应用检测、安装以及企业内部商店的实现
一、企业内部应用检测和更新升级 A应用检测是否安装B应用 canOpenApp():boolean{ try { let link schB://com.example.test/open; // 替换成你目标应用的link串儿 let canOpen bundleManager.canOpenLink(link); console.log("canOpen:"canOpen…...