MoonSharp 文档五

news2025/3/14 22:14:29

目录

13.Coroutines(协程)

Lua中的协程

从CLR代码中的协程

从CLR代码中的协程作为CLR迭代器

注意事项

抢占式协程

14.Hardwire descriptors(硬编码描述符)

为什么需要“硬编码”

什么是“硬编码”

如何进行硬编码

硬编码的优缺点

硬编码是实现IL2CPP、AOT或iOS兼容性的必要条件吗?

术语表

15.Sandboxing(沙盒)

为什么需要沙盒化

沙盒化检查清单

移除“危险”的 API

16.Tips and tricks for Unity3D(Unity3D的提示和技巧)

支持的平台

其他建议

使用更显式的构造函数之一初始化脚本加载器

17.FAQ / Recipes

如何重定向打印函数的输出?

如何将输入重定向到Lua程序?

如何重定向Lua程序的IO流?

如何限制脚本在不丢失状态的情况下执行的指令数?


MoonSharp 文档一-CSDN博客

MoonSharp 文档二-CSDN博客

MoonSharp 文档三-CSDN博客

MoonSharp 文档四-CSDN博客

13.Coroutines(协程)

来自 C# 和 Lua。

文档地址:MoonSharp

Lua中的协程

Lua 中的协程是开箱即用的支持。实际上,只要你不故意排除协程模块(参见沙盒化),它们就可以免费使用。有很多注意事项(这些也偶然适用于原始的 Lua 实现),并在下面的 “注意事项” 部分进行了讨论。

使用任何 Lua 协程教程来操作它们。

从CLR代码中的协程

协程可以通过脚本 CreateCoroutine 方法创建,该方法接受一个必须是函数的 DynValue。

string code = @"
	return function()
		local x = 0
		while true do
			x = x + 1
			coroutine.yield(x)
		end
	end
	";

// Load the code and get the returned function
Script script = new Script();
DynValue function = script.DoString(code);

// Create the coroutine in C#
DynValue coroutine = script.CreateCoroutine(function);

// Resume the coroutine forever and ever..
while (true)
{
	DynValue x = coroutine.Coroutine.Resume();
	Console.WriteLine("{0}", x);
}

从CLR代码中的协程作为CLR迭代器

可以像调用迭代器一样调用协程:

string code = @"
	return function()
		local x = 0
		while true do
			x = x + 1
			coroutine.yield(x)
			if (x > 5) then
				return 7
			end
		end
	end
	";

// Load the code and get the returned function
Script script = new Script();
DynValue function = script.DoString(code);

// Create the coroutine in C#
DynValue coroutine = script.CreateCoroutine(function);

// Loop the coroutine 
string ret = "";

foreach (DynValue x in coroutine.Coroutine.AsTypedEnumerable())
{
	ret = ret + x.ToString();
}

Assert.AreEqual("1234567", ret);

注意事项

现在我们来到了协程相关内容中最重要的部分。就像在原始的 Lua 中一样,无法从嵌套调用中执行 yield 操作。

特别是在 MoonSharp 中,如果你在从 Lua 调用的 C# 函数中调用一个脚本,你不能使用 yield 来恢复到 C# 调用外部的协程。

不过有一个解决办法:返回一个 TailCallRequest 类型的 DynValue

return DynValue.NewTailCallReq(luafunction, arg1, arg2...); 

还可以指定一个 continuation(延续)——这是一段函数,它将在尾调用执行完成后被调用。

在 99% 的情况下,这可能是过度设计——甚至在大多数情况下,Lua 标准库也无法正确处理回调与 yield 的结合。但如果你计划自己实现像 `load`、`pcall` 或 `coroutine.resume` 这样的 API,这就是必需的。

另外,在某些边缘情况下,MoonSharp 处理 yield 的方式与标准 Lua 不同(在我尝试过的所有情况中,MoonSharp 的方式都更好,但谁知道呢)。例如,`tostring()` 支持在调用 `__tostring` 元方法时执行 yield 操作,而不会引发错误。

抢占式协程

在 MoonSharp 中,即使协程没有调用 `coroutine.yield`,也可以将其挂起。例如,如果想要非破坏性地限制脚本占用的 CPU 时间,这可能会很有用。但为了保持脚本的一致性,有一些需要注意的地方。

让我们从一个例子开始:

string code = @"
	function fib(n)
		if (n == 0 or n == 1) then
			return 1;
		else
			return fib(n - 1) + fib(n - 2);
		end
	end
	";

// Load the code and get the returned function
Script script = new Script(CoreModules.None);
script.DoString(code);

// get the function
DynValue function = script.Globals.Get("fib");

// Create the coroutine in C#
DynValue coroutine = script.CreateCoroutine(function);

// Set the automatic yield counter every 10 instructions. 
// 10 is likely too small! Use a much bigger value in your code to avoid interrupting too often!
coroutine.Coroutine.AutoYieldCounter = 10;

int cycles = 0;
DynValue result = null;

// Cycle until we get that the coroutine has returned something useful and not an automatic yield..
for (result = coroutine.Coroutine.Resume(8); 
	result.Type == DataType.YieldRequest;
	result = coroutine.Coroutine.Resume()) 
{
	cycles += 1;
}

// Check the values of the operation
Assert.AreEqual(DataType.Number, result.Type);
Assert.AreEqual(34, result.Number);

步骤如下:

1. 创建一个协程 

2. 将 `AutoYieldCounter` 设置为一个大于 0 的数字。1000 是一个不错的起点,可以根据需要调整。这个数字表示在执行多少条指令后,协程会主动挂起并返回给调用者。  

3. 调用 `coroutine.Coroutine.Resume(...)` 并传入适当的参数。

4. 如果上述调用的返回类型是 `DataType.YieldRequest`,则不带参数调用 `coroutine.Coroutine.Resume()`。 

5. 重复上一步,直到返回一个真正的结果类型。 

6. 完成。  

注意事项:

1. 如果代码重新进入(例如,`string.gsub` 的回调函数),在返回到“可挂起状态”之前,它不会被抢占。

2. 将标准协程操作与抢占式操作混合使用是可能的,但危险且复杂。请记住,协程可以在任何地方被抢占式挂起,因此无法保证操作的原子性等。如果混合使用,请务必小心。

14.Hardwire descriptors(硬编码描述符

自2016年以来帮助 AOT 和 IL2CPP

文档地址:MoonSharp

如果您不知道本页中使用的某些术语,请参阅底部的术语表部分。

为什么需要“硬编码”

MoonSharp 像大多数类库一样,使用反射,有时还会在运行时生成代码,以便从 Lua 脚本中访问 C# 代码。

从根本上说,MoonSharp 已经比大多数其他脚本引擎更加温和,原因在于:

理论上,它可以在完全不使用反射的情况下运行(尽管需要编写大量代码),这有助于提高速度并避免一些麻烦(如 IL2CPP 的 link.xml 问题)。
它不会在不应该生成IL代码的平台上生成IL代码(如 Xamarin 的 iOS、Unity 的 IL2CPP 平台等)。
前一点不会导致功能损失,只是速度会稍微慢一些。
这些都是优点,并且带来了很大的兼容性,但还可以做得更多。

如果大部分反射都被移除(剩下的少量反射也无害),并且还能获得更好的性能,那会怎样?

听起来好得不像真的?从某种意义上说,是的。这就是“硬编码”的用武之地,但需要付出一些代价。

什么是“硬编码”

这个想法很简单。为了避免反射,目前唯一的方法是编写大量的 C# 胶水代码。非常多。而且是难以编写的 C# 代码。但这并不是必须的——我们可以稍微简化一下编写方式。但这仍然是一项枯燥的工作,而且很容易出错。

然而,事实证明,这种枯燥、困难且容易出错的工作正是自动化的理想场景。而 MoonSharp 拥有完成这项工作所需的所有信息。

所以,简而言之,通过“硬编码”,MoonSharp 可以生成一堆不需要进一步反射类型就能运行的 C# 代码。

如何进行硬编码

很简单。嗯,几乎很简单。

MoonSharp 需要将已注册的所有类型的信息导出到某个地方。为此,需要编写一小段临时代码:

Table dump = UserData.GetDescriptionOfRegisteredTypes(true);
File.WriteAllText(@"c:\temp\testdump.lua", dump.Serialize());

重要的是,上述代码必须在所有类型都已注册之后运行。因此,硬编码的第一条规则是确保所有注册的顺序正确。

现在,可以使用 MoonSharp 的 REPL 解释器生成代码:

moonsharp -W c:\temp\testdump.lua c:\temp\out.cs --internals --class:MyClass --namespace:MyNamespace

此时,生成过程可能会输出大量警告/错误。它们会显示在控制台输出中,并作为代码中的注释。即使存在警告/错误,生成的代码仍然可以工作,但请花时间阅读这些警告/错误,因为如果你的脚本代码引用了触发这些警告/错误的成员,行为可能会与预期不同。

如果你没有 Windows 电脑,你可以轻松地使用 Mono 在 Mac 或 Linux 上运行 MoonSharp 解释器!

生成的代码将包含一个单一的公共静态类,其中有一个公共的静态 `Initialize` 方法,你应该在使用 MoonSharp 进行任何其他操作之前调用这个方法。非常简单。

如果你注册了一个系统类型(例如,数组),在硬编码时可能会遇到一些问题。原因是硬编码将使用生成 “dump” 时运行时的类型定义,如果你更改了 .NET 版本或平台,运行时可能会有所不同。虽然这看起来像是一个边缘情况,但在 Unity 的 Windows Phone 和 Windows Store 应用中会发生这种情况。在最坏的情况下,可以在生成的代码周围加上条件编译指令。

硬编码的优缺点

优点:

•  大幅减少反射的使用
•  在元数据被剥离的情况下(如IL2CPP),无需白名单类型
•  无需运行时代码生成
•  显著提升性能,尤其是在不支持运行时代码生成的平台上

缺点:

•  需要在工作流程中加入代码生成步骤
•  代码生成仅支持 C# 或 VB.NET
•  暴露的类型和成员必须对其他类可访问——简而言之,必须是`public`的,或者在同一程序集中为`internal`
•  某些类型的成员可能不受支持(例如事件,至少在当前版本中)  
•  值类型的设置器可能无法正常工作——或者比平时更糟,尽量避免使用它们
•  硬编码系统目前涵盖了所有通过 `UserDataType` 注册的类型,而不传递用户数据描述符。除了自定义描述符(显然需要你自己处理)之外,这意味着与 `PropertyTableAssigner` 和扩展方法一起使用的类型不包括在内。通常这问题不大,因为它们往往用于 IL2CPP 启发式算法可见的类型,未来可能会实现支持。

硬编码是实现IL2CPP、AOT或iOS兼容性的必要条件吗?

AOT 兼容性通过 `PlatformAccessor` 管理。实际上,唯一的行为变化是在 AOT 平台上不执行运行时代码生成,而是使用纯反射。

对于 IL2CPP 兼容性,硬编码简化了这一过程——通过消除为不应剥离的元数据维护 `link.xml` 文件的需求——并使其更高效,因为反射速度较慢。但你仍然可以通过向 `link.xml` 添加条目来实现兼容性。

术语表

反射(Reflection):  
一组允许代码“检查”自身并最终调用方法、读取和写入字段及属性等的类型和方法。虽然功能强大,但速度较慢。详见 MSDN 文档。

运行时代码生成(Runtime code generation):  
在运行时生成代码以优化通过反射完成的操作的做法。MoonSharp 在某些地方使用了这一技术,但在 AOT 平台上会被禁用。

IL(Intermediate Language,中间语言):  
.NET/mono 程序集中的代码以 IL(中间语言字节码)形式存储。这种字节码不能直接执行,必须在执行前转换为本地指令。

JIT(Just-In-Time,即时编译):  
通常,当 .NET 或 mono 加载程序集时,它们会对IL代码进行即时编译,将其转换为本地代码。这也可能在程序集的生命周期后期发生——例如,如果泛型类型的某个类型参数是值类型,通常会即时重新编译。

AOT(Ahead-of-Time,预先编译):  
mono 提供的一种选项(某种程度上 ngen 和 .NET Native 也提供,但与此讨论无关,至少目前如此),可以提前将代码编译为本地代码或其他形式。这并不简单,可能无法编译所有需要的代码。例如,如果使用反射来实例化代码中从未引用的类型,则该特定代码可能未被编译。在 iOS 设备上运行需要 AOT 执行。

IL2CPP:  
一种将 IL 转换为 C++ 源代码的出色软件。它是那种极难编写但大多数人谈论它时只是为了抱怨的软件。说真的,它试图解决的问题非常复杂,需要一些合作来确保兼容性。特别是,除了所有 AOT 问题(IL2CPP 必须使用 AOT)外,IL2CPP 还会对程序集元数据进行选择性剥离,这可能会干扰反射。在 Unity3D 下,IL2CPP 是 iOS、tvOS 和 WebGL 的强制要求,并在更多平台上作为选项提供。

link.xml:  
一个告诉 IL2CPP 应保留哪些类型的元数据的文件。

值类型(Value-type):  
值类型是按值传递而不是按引用传递的类型。它包括数值基元类型、枚举和结构体。当谈论值类型问题时,通常指的是结构体。详见 MSDN 上的结构体文档。最佳实践建议值类型应为不可变的,即它们的字段和属性应为只读的,如果需要更改它们,应创建一个新对象(对于结构体来说,这非常廉价)。MoonSharp 与可变结构体的兼容性不佳,因为它们是一种与许多事物都不兼容的奇怪存在,因此请不要使用它们。如果必须使用,请考虑使用代理对象进行变通。

15.Sandboxing(沙盒)

限制 Lua 脚本的功能

文档地址:MoonSharp

为什么需要沙盒化

沙盒化很可能是你使用 MoonSharp 时的关键功能。除非你以某种方式控制脚本提供者(可能还包括用户),否则在运行时加载脚本(或任何类型的代码,有时甚至是数据)时存在一个基本的信任问题:安全性。

例如,假设你正在编写一款视频游戏,并使用 Lua 使游戏“可修改”。用户可以访问某个社区网站并下载包含新关卡、AI等的模组,这些模组都使用 MoonSharp 编写以实现最大灵活性。大家都很开心。现在想象一下,如果某个恶意用户上传了一些隐藏在漂亮关卡中的恶意脚本,会发生什么……比如一个在桌面上创建 .exe 文件的脚本,其他用户可能会不小心点击它。

除非你信任用户,或者明显可以防止恶意使用,否则你不想向普通用户公开某些 API(如`os`、`io`和`file`)。

沙盒化检查清单

这份清单可以帮助你入门,但并不全面。

1. 确保脚本无法访问所有“危险”的标准 API。这肯定包括`io`、`os`和`file`,但根据你的脚本和偏执程度,可能还包括更多。请参阅下一章,了解如何轻松地使整个API集不可访问。

2. 不要使用 `InteropRegistrationPolicy.Automatic`。永远不要。

3. 检查你是否向脚本暴露了不应暴露的类型或类型成员。避免直接暴露你不拥有的类型,如 .NET 框架类型或 Unity 类型。如果需要,请参阅关于“代理对象”的部分,以及如何使用 `MoonSharpHide` 和 `MoonSharpHidden`。

4. 如果你希望脚本的某些部分访问这些危险的 API,请将它们放在单独的 `Script` 对象中,并确保其他脚本无法访问这些对象。

5. 如果绝对必须仅对脚本的一部分进行“沙盒化”,请参考这份经典指南。

移除“危险”的 API

移除危险 API 的最简单方法是使用接受 `CoreModules` 枚举的 `Script` 构造函数。

`CoreModules` 枚举的含义非常直观:

/// <summary>
/// Enumeration (combinable as flags) of all the standard library modules
/// </summary>
[Flags]
public enum CoreModules
{
	/// <summary>
	/// Value used to specify no modules to be loaded (equals 0).
	/// </summary>
	None = 0,

	/// <summary>
	/// The basic methods. Includes "assert", "collectgarbage", "error", "print", "select", "type", "tonumber" and "tostring".
	/// </summary>
	Basic = 0x40,
	/// <summary>
	/// The global constants: "_G", "_VERSION" and "_MOONSHARP".
	/// </summary>
	GlobalConsts = 0x1,
	/// <summary>
	/// The table iterators: "next", "ipairs" and "pairs".
	/// </summary>
	TableIterators = 0x2,
	/// <summary>
	/// The metatable methods : "setmetatable", "getmetatable", "rawset", "rawget", "rawequal" and "rawlen".
	/// </summary>
	Metatables = 0x4,
	/// <summary>
	/// The string package
	/// </summary>
	String = 0x8,
	/// <summary>
	/// The load methods: "load", "loadsafe", "loadfile", "loadfilesafe", "dofile" and "require"
	/// </summary>
	LoadMethods = 0x10,
	/// <summary>
	/// The table package 
	/// </summary>
	Table = 0x20,
	/// <summary>
	/// The error handling methods: "pcall" and "xpcall"
	/// </summary>
	ErrorHandling = 0x80,
	/// <summary>
	/// The math package
	/// </summary>
	Math = 0x100,
	/// <summary>
	/// The coroutine package
	/// </summary>
	Coroutine = 0x200,
	/// <summary>
	/// The bit32 package
	/// </summary>
	Bit32 = 0x400,
	/// <summary>
	/// The time methods of the "os" package: "clock", "difftime", "date" and "time"
	/// </summary>
	OS_Time = 0x800,
	/// <summary>
	/// The methods of "os" package excluding those listed for OS_Time. These are not supported under Unity.
	/// </summary>
	OS_System = 0x1000,
	/// <summary>
	/// The methods of "io" and "file" packages. These are not supported under Unity.
	/// </summary>
	IO = 0x2000,
	/// <summary>
	/// The "debug" package (it has limited support)
	/// </summary>
	Debug = 0x4000,
	/// <summary>
	/// The "dynamic" package (introduced by MoonSharp).
	/// </summary>
	Dynamic = 0x8000,


	/// <summary>
	/// A sort of "hard" sandbox preset, including string, math, table, bit32 packages, constants and table iterators.
	/// </summary>
	Preset_HardSandbox = GlobalConsts | TableIterators | String | Table | Basic | Math | Bit32,
	/// <summary>
	/// A softer sandbox preset, adding metatables support, error handling, coroutine, time functions and dynamic evaluations.
	/// </summary>
	Preset_SoftSandbox = Preset_HardSandbox | Metatables | ErrorHandling | Coroutine | OS_Time | Dynamic,
	/// <summary>
	/// The default preset. Includes everything except "debug" as now.
	/// Beware that using this preset allows scripts unlimited access to the system.
	/// </summary>
	Preset_Default = Preset_SoftSandbox | LoadMethods | OS_System | IO,
	/// <summary>
	/// The complete package.
	/// Beware that using this preset allows scripts unlimited access to the system.
	/// </summary>
	Preset_Complete = Preset_Default | Debug,

}

16.Tips and tricks for Unity3D(Unity3D的提示和技巧)

为在 Unity 上使用 MoonSharp 的用户提供的快速提示集

文档地址:MoonSharp

支持的平台

一般来说,MoonSharp 的目标是支持所有平台。然而,在 Unity 中测试 MoonSharp 在所有平台上的表现是非常困难的,几乎是不可能的。

因此,平台被分为不同的等级。

1.预计完全支持独立的 Windows、Linux 和 OS/X * 安卓 * iOS * tvOS

2.预计零星支持,将在可能的情况下测试小问题/不支持的功能 WebGL * Windows 应用商店应用程序 Windows Phone

3.应该有效,但我很难提供支持其他层没有的东西

4.不支持,您只能自己使用目前尚不清楚,将进行更新以防

其他建议

•  如果可能,不要暴露 Unity 类型  
•  尽可能使用代理对象  
•  在运行于 IL2CPP 和/或 AOT 平台之前,使用硬编码  
•  如果可能,永远不要暴露结构体  

使用更显式的构造函数之一初始化脚本加载器

使用 UnityAssetsScriptLoader 的显式构造函数来注册所有脚本文件。通过在项目的最开始使用这个小片段,您不需要将 Unity 自带的库添加到 link.xml 中,就可以在 IL2CPP 平台上运行。

示例:

Dictionary<string, string> scripts = new  Dictionary<string, string>();

 object[] result = Resources.LoadAll("Lua", typeof(TextAsset));

 foreach(TextAsset ta in result.OfType<TextAsset>())
 {
     scripts.Add(ta.name, ta.text);
 }

 Script.DefaultOptions.ScriptLoader = new MoonSharp.Interpreter.Loaders.UnityAssetsScriptLoader(scripts);

17.FAQ / Recipes

常见问题的简单示例

文档地址:MoonSharp

如何重定向打印函数的输出?

script.Options.DebugPrint = s => { Console.WriteLine(s); }

如何将输入重定向到Lua程序?

script.Options.DebugInput = () => { return Console.ReadLine(); }

如何重定向Lua程序的IO流?

IoModule.SetDefaultFile(script, Platforms.StandardFileType.StdIn, myInputStream);
IoModule.SetDefaultFile(script, Platforms.StandardFileType.StdOut, myOutputStream);
IoModule.SetDefaultFile(script, Platforms.StandardFileType.StdErr, myErrorStream);

如何限制脚本在不丢失状态的情况下执行的指令数?

参考 Preemptive coroutines.

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2315100.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性

最近在思考一个问题&#xff1a;如何能够更好的分享主流框架源码学习笔记&#xff08;主要是源码部分&#xff09;?让有缘刷到的同学既可以有所收获&#xff0c;还能保持对相关技术架构探讨学习热情和兴趣。以及自己也保持较高的分享热情和动力。 今天尝试用一个SQL查询作为引…

ArrayList底层结构和源码分析笔记

参考视频&#xff1a;韩顺平Java集合 ArrayList特点 ArrayList 可以加入 null&#xff0c;包括多个。 ArrayList 是由数组来实现数据存储的 ArrayList 基本等同于 Vector&#xff0c;除了 ArrayList 是线程不安全&#xff08;执行效率高&#xff09;。在多线程情况下&#xf…

[内网渗透] 红日靶场2

环境配置 靶场地址: http://vulnstack.qiyuanxuetang.net/vuln/wiki/ 环境配置可以看这个: https://www.bilibili.com/video/BV1De4y1a7Ps/?spm_id_from333.337.search-card.all.click&vd_sourcecf73ac8de9b7c0322b1bccf77de91c5dNAT模式分配111段, DHCP也要更改 再添加…

MySQL 企业版 TDE加密后 测试和问题汇总

一、测试keyring file 1.1 当keyring file文件丢失或者被篡改 结论&#xff1a;不影响当前正在运行的数据库&#xff0c;但是在重启服务后会启动失败出现报错。 tail -n 100 /var/log/mysql/error.log 报错信息如下&#xff1a; 2025-03-12T08:04:54.668847Z 1 [ERROR] [M…

Unity 封装一个依赖于MonoBehaviour的计时器(下) 链式调用

[Unity] 封装一个依赖于MonoBehaviour的计时器(上)-CSDN博客 目录 1.加入等待间隔时间"永远执行方法 2.修改为支持链式调用 实现链式调用 管理"链式"调度顺序 3.测试 即时方法​编辑 "永久"方法 链式调用 ​4.总结 1.加入等待间隔时间&qu…

套接字缓冲区以及Net_device

基础网络模型图 一般网络设计分为三层架构和五层设计&#xff1a; 一、三层架构 用户空间的应用层 位于最上层&#xff0c;是用户直接使用的网络应用程序&#xff0c;如浏览器、邮件客户端、即时通讯软件等。这些程序通过系统调用&#xff08;如 socket 接口&#xff09;向内核…

2024下半年真题 系统架构设计师 案例分析

案例一 软件架构 关于人工智能系统的需求分析&#xff0c;给出十几个需求。 a.系统发生业务故障时&#xff0c;3秒内启动 XXX&#xff0c;属于可靠性 b.系统中的数据进行导出&#xff0c;要求在3秒内完成&#xff0c;属于可用性 c.质量属性描述&#xff0c;XXX&#xff0c;属…

c++介绍智能指针 十二(2)

智能指针share_ptr,与unique_ptr不同&#xff0c;多个shar_ptr对象可以共同管理一个指针&#xff0c;它们通过一个共同的引用计数器来管理指针。当一个智能指针对象销毁时&#xff0c;计数器减一。当计数器为0时&#xff0c;会将所指向的内存对象释放。 #include<memory>…

西门子S7-1200 PLC远程调试技术方案(巨控GRM532模块)

三步快速实现远程调试 硬件部署 准备西门子S7-1200 PLC、巨控GRM552YW-C模块及编程电脑。GRM552YW-C通过网口与PLC连接&#xff0c;支持4G/5G/Wi-Fi/有线网络接入&#xff0c;无需复杂布线。 软件配置 安装GVCOM3配置软件&#xff0c;注册模块&#xff08;输入唯一序列号与密…

Mac上更改默认应用程序

Mac上为某些文件设置默认打开应用的时候&#xff0c;刚开始是通过打开方式&#xff0c;其他里面&#xff0c;勾选始终以此方式打开&#xff0c;但实际上这个功能并不太好用&#xff0c;经常会让人误以为已经设置好了。但是实际上只是在当前目录起作用。真正解决这个问题可以按照…

【开源+代码解读】Search-R1:基于强化学习的检索增强大语言模型框架3小时即可打造个人AI-search

大语言模型(LLMs)在处理复杂推理和实时信息检索时面临两大挑战:知识局限性(无法获取最新外部知识)和检索灵活性不足(传统方法依赖固定检索流程)。现有方法如检索增强生成(RAG)和工具调用(Tool-Use)存在以下问题: RAG:单轮检索导致上下文不足,无法适应多轮交互场景…

贪心算法和遗传算法优劣对比——c#

项目背景&#xff1a;某钢管厂的钢筋原材料为 55米&#xff0c;工作需要需切割 40 米&#xff08;1段&#xff09;、11 米&#xff08;15 段&#xff09;等 4 种规格 &#xff0c;现用贪心算法和遗传算法两种算法进行计算&#xff1a; 第一局&#xff1a;{ 40, 1 }, { 11, 15…

网络安全防护总体架构 网络安全防护工作机制

1 实践内容 1.1 安全防范 为了保障"信息安全金三角"的CIA属性、即机密性、完整性、可用性&#xff0c;信息安全领域提出了一系列安全模型。其中动态可适应网络安全模型基于闭环控制理论&#xff0c;典型的有PDR和P^2DR模型。 1.1.1 PDR模型 信息系统的防御机制能…

SpringCloud带你走进微服务的世界

认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部…

Python设计模式 - 建造者模式

定义 建造者模式是一种创建型设计模式&#xff0c;主要用于构建包含多个组成部分的复杂对象。它将对象的构建过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的对象表示。 结构 抽象建造者&#xff08;Builder&#xff09;&#xff1a;声明创建产品的各个部件的方…

在 Ubuntu 上安装和配置 Docker 的完整指南

Docker 是一个开源的平台&#xff0c;旨在简化应用程序的开发、部署和运行。通过将应用程序及其依赖项打包到容器中&#xff0c;Docker 确保应用程序可以在任何环境中一致地运行。 目录 前言安装前的准备安装 Docker 步骤 1&#xff1a;更新包索引步骤 2&#xff1a;安装必要…

网络安全之数据加密(DES、AES、RSA、MD5)

刚到公司时&#xff0c;我的工作就是为app端提供相应的接口。之前app使用的是PHP接口&#xff0c;对数据加密方面做得比较少。到使用java接口时&#xff0c;老大开始让我们使用DES加密&#xff0c;进行数据传输&#xff0c;但是后来觉得DES是对称加密&#xff0c;密钥存在客户端…

基于SpringBoot的“校园周边美食探索及分享平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“校园周边美食探索及分享平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 校园周边美食探索及分享平台结构图…

vscode关闭仓库后如何打开

vscode源代码管理->更改->代码 关闭仓库后如何打开。 关闭仓库操作 打开仓库操作 1.按下 Ctrl Shift P&#xff08;Windows/Linux&#xff09;或 Cmd Shift P&#xff08;Mac&#xff09;打开命令面板。 2.在命令面板中输入 Git: Open Repository&#xff0c;然后选…

DeepSeek-R1 论文阅读总结

1. QA问答&#xff08;我的笔记&#xff09; Q1: DeepSeek如何处理可读性问题&#xff1f; 通过构建冷启动数据&#xff08;数千条长CoT数据&#xff09;微调基础模型&#xff0c;结合多阶段训练流程&#xff08;RL训练、拒绝采样生成SFT数据&#xff09;&#xff0c;并优化输…