实战指南
前言
本文是 LeanCLR 的实战指南,基于前文第 38 篇(生态概览)、第 39 篇(架构解析)和第 40 篇(源码剖析)的理论基础,面向希望将 LeanCLR 集成到实际项目中的开发者。内容涵盖环境搭建、基本使用、高级特性以及常见问题排查,帮助读者从零开始掌握 LeanCLR 的集成与开发流程。文中的代码示例和对比表格均来自真实项目经验,可直接应用于生产环境。
本文的写作动机源于一个现实需求:越来越多的项目需要在非 Unity 环境中执行 C# 逻辑。无论是游戏服务器的战斗计算、Web 浏览器的数据处理、嵌入式设备的业务规则引擎,还是边缘计算节点的数据聚合,LeanCLR 都提供了一条高效且轻量的路径。它不像 Mono 那样庞大完整,也不像 .NET Native 那样平台受限,而是做到了恰到好处的精简——保留了 IL 解释执行的核心能力,舍弃了桌面级运行时那些不必要的重量级依赖。
本文适合具备 C++ 和 C# 基础开发经验的读者。如果你已经阅读过第 38 篇对 LeanCLR 生态的宏观介绍、第 39 篇对其运行时架构的深入分析以及第 40 篇对核心源码的逐层解读,那么本文将为你补齐最后一块拼图——动手实践。我们将从下载源码编译开始,一步步搭建起可运行的 LeanCLR 项目,并深入探索热更新、热修复、宿主交互和性能调优等关键场景的实际用法和常见陷阱。
一、LeanCLR 的环境搭建
1.1 获取源码
LeanCLR 托管在 GitHub 上,使用以下命令克隆最新代码:
git clone https://github.com/focus-creative-games/leanclr.git
cd leanclr
建议切换到稳定发布版本,而非直接使用 master 分支。可以通过 git tag 查看可用版本,选择最新的语义化版本标签进行切换,例如 git checkout v1.0.0。稳定版本经过更充分的测试,适合生产环境使用。
源码目录结构说明:核心运行时位于 src/leanclr/ 目录下,包含解释器(interpreter)、元数据加载器(metadata loader)和 GC 模块。头文件位于 include/leanclr/ 目录下,公开了完整的 C API。samples 目录包含多个示例工程,是从零上手的最佳参考。建议先运行 samples 中的示例项目确认环境配置正确,再开始自己的项目开发。
1.2 构建依赖
LeanCLR 基于业界标准的构建工具链,以下是必需的构建依赖。这些工具在主流操作系统上均有成熟的支持,安装过程通常只需几条命令:
- CMake ≥ 3.15:跨平台构建系统,负责生成各平台的编译配置
- C++17 编译器:GCC 9+(Linux)、Clang 10+(macOS)、MSVC 2019+(Windows)
- 可选 - WebAssembly 构建:Emscripten SDK ≥ 3.1.0
对于 .NET/C# 侧,需要 .NET SDK 6.0 或更高版本,用于将 C# 源码编译为托管程序集。
1.3 构建命令
LeanCLR 支持原生构建和 WebAssembly 构建,分别适用于不同的目标平台:
# Native build(Linux/macOS/Windows)
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --target leanclr
# WASM build(浏览器环境)
mkdir build_wasm && cd build_wasm
emcmake cmake .. -DPLATFORM=WASM
emmake make leanclr
构建成功后,库文件位于 build/lib/ 目录下,头文件位于 include/ 目录下。对于跨平台项目,建议在构建脚本中封装不同平台的构建参数,实现一键构建。例如在 scripts/build.sh 中根据 $(uname) 自动选择编译器路径和链接选项。
1.4 项目结构初始化
一个典型的 LeanCLR 项目组织如下:
my_project/
├── CMakeLists.txt # 项目构建配置
├── src/
│ ├── host_main.cpp # 宿主应用(C++ 入口)
│ └── my_app/ # C# 源码目录
│ ├── Program.cs
│ └── MyClass.cs
└── scripts/
└── build.sh # 构建脚本
CMakeLists.txt 的关键配置如下:
cmake_minimum_required(VERSION 3.15)
project(MyLeanCLRApp)
find_package(LeanCLR REQUIRED)
add_executable(my_host src/host_main.cpp)
target_link_libraries(my_host PRIVATE leanclr::leanclr)
1.5 各平台对比
不同平台的构建配置和运行时特性有所差异,下表概括了主要区别:
| 平台 | 编译器 | 构建工具 | 运行时依赖 | 体积 |
|---|---|---|---|---|
| Linux x86_64 | GCC/Clang | CMake+Make | 无 | ~1.5 MB |
| Windows x64 | MSVC | CMake+MSBuild | VC++ Redist | ~2.0 MB |
| WebAssembly | emcc | emcmake+emmake | 无 | ~1.0 MB |
| ARM Linux | GCC (arm-linux) | CMake+Make | 无 | ~1.8 MB |
1.6 验证安装
构建完成后,运行官方示例程序验证安装是否成功。这是确认整个工具链正确工作的最简单方法:
./bin/leanclr_sample
预期输出如下:
LeanCLR initialized successfully
Assembly loaded: SampleApp.dll
Main() returned: 42
如果看到上述输出,说明 LeanCLR 已正确安装并可以正常工作。如果输出不符合预期,请检查上一节的常见构建错误对照表进行排查。
1.7 常见构建错误及解决方法
构建过程中可能遇到以下典型问题。这些错误大多源于环境配置差异,对照以下排查方法通常可以快速解决:
CMake 找不到 LeanCLR 包:确保 leanclr-config.cmake 文件位于 CMake 搜索路径中。可以通过设置 -DLeanCLR_DIR=/path/to/leanclr/cmake 显式指定路径。
MSVC 链接器报 LNK2019 错误:检查项目配置的运行库类型(/MD 或 /MT)是否与 LeanCLR 库一致。混用不同运行库会导致符号解析失败。
WASM 构建卡死或报内存不足:Emscripten 默认内存限制较低,可以通过 -s TOTAL_MEMORY=256MB 参数增大内存上限。另外确认 emcc 版本 ≥ 3.1.0,旧版本对 C++17 特性支持不完整。
构建配置建议:生产环境建议开启 LTO(链接时优化)以减小库体积并提升运行时性能。在 CMake 中添加 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON 即可。调试阶段建议关闭优化(Debug 模式),以便获取完整的堆栈跟踪信息。
二、LeanCLR 的基本使用
2.1 加载程序集
在 C++ 宿主中加载并执行 C# 程序集是 LeanCLR 的核心操作。以下是一个完整的加载流程,涵盖从创建运行时时到销毁清理的完整生命周期:
// Step 1: 创建运行时实例
leanclr_config cfg = LEANCLR_DEFAULT_CONFIG;
cfg.memory_limit = 128 * 1024 * 1024; // 设定内存上限 128MB
leanclr_runtime* rt = leanclr_create(&cfg);
第一步创建运行时实例,配置内存上限、GC 参数和日志级别等选项。配置完成后调用 leanclr_create 初始化运行时内部组件(元数据模块、解释器引擎、GC 子系统等)。
// Step 2: 从文件加载程序集
leanclr_load_assembly_file(rt, "MyApp.dll");
第二步从磁盘加载编译好的 .NET 程序集。leanclr_load_assembly_file 内部会解析 PE 文件格式、读取元数据表、注册类型和方法到运行时的类型系统。
// Step 3: 调用静态方法
leanclr_value result;
leanclr_execute_static(
rt,
"MyApp.Program", // 完整类型名
"Main", // 方法名
0, // 参数个数
NULL, // 参数数组
&result // 返回值
);
printf("Result: %d\n", result.i32);
第三步通过类型名和方法名调用静态方法。leanclr_execute_static 会在运行时查找指定的类型和方法,解析方法元数据,创建解释器栈帧,然后执行 IL 指令循环。
// Step 4: 清理资源
leanclr_destroy(rt);
最后一步销毁运行时实例,释放所有已分配的资源,包括元数据缓存、解释器栈帧和 GC 堆空间。
2.2 编写 C# 代码
LeanCLR 执行的 C# 代码使用标准的 .NET 语法,只需编译为常规的程序集即可。编译命令使用 csc(Mono)或 dotnet build(.NET SDK),目标框架需设为 .NET Standard 2.0 以确保最大兼容性:
// MyApp/Program.cs
using System;
namespace MyApp
{
public class Program
{
public static int Main()
{
Console.WriteLine("Hello from LeanCLR!");
var calc = new Calculator();
return calc.Add(3, 4);
}
}
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
}
编译命令(从项目根目录执行):
cd src/my_app
dotnet build -c Release -o ../../build/assemblies
2.3 与宿主语言的交互
LeanCLR 支持宿主(C++)与托管(C#)之间的双向调用。宿主注册回调函数供 C# 调用是最常见的交互模式,这使得宿主可以将底层系统能力(如文件 IO、网络请求、硬件控制等)安全地暴露给 C# 业务层使用:
// 注册一个原生回调,供 C# 调用
static void OnCustomEvent(const char* name, int value) {
printf("C# called: %s = %d\n", name, value);
}
// 在宿主初始化时注册回调
leanclr_register_callback(rt, "CustomEvent", OnCustomEvent);
对应的 C# 侧代码:
// C# 侧回调到宿主
public static class HostBridge
{
// 该声明将绑定到原生回调
public static void CustomEvent(string name, int value);
}
// 使用示例
HostBridge.CustomEvent("PlayerDied", score);
2.4 类型和方法调用完整流程
下表展示了不同 C# 操作对应的 LeanCLR C API,方便开发者在编码时快速查阅:
| C# 操作 | LeanCLR C API | 说明 |
|---|---|---|
new T() |
leanclr_create_object |
实例化对象 |
obj.Method() |
leanclr_call_virtual |
虚方法调用 |
T.Static() |
leanclr_call_static |
静态方法调用 |
obj.field |
leanclr_get_field / leanclr_set_field |
字段读写 |
array[i] |
leanclr_get_array_element |
数组元素访问 |
(T)obj |
leanclr_cast_object |
类型转换 |
typeof(T) |
leanclr_get_type |
获取类型信息 |
2.5 参数传递与返回值处理
跨边界调用时,参数和返回值的类型映射需要特别注意:
| C# 类型 | LeanCLR C 类型 | 说明 |
|---|---|---|
int / System.Int32 |
leanclr_value.i32 |
32 位有符号整数 |
long / System.Int64 |
leanclr_value.i64 |
64 位有符号整数 |
float / System.Single |
leanclr_value.f32 |
32 位浮点数 |
double / System.Double |
leanclr_value.f64 |
64 位浮点数 |
bool / System.Boolean |
leanclr_value.i32 |
布尔值映射为 0/1 |
string / System.String |
leanclr_value.obj |
需通过字符串 API 转换 |
object / System.Object |
leanclr_value.obj |
通用对象引用 |
构造参数的示例代码:
// 调用带参数的 C# 方法
leanclr_value args[2];
args[0].i32 = 10; // 第一个参数:int
args[1].f32 = 3.14f; // 第二个参数:float
leanclr_value ret;
leanclr_execute_static(
rt, "MyApp.Calculator",
"Compute", 2, args, &ret
);
printf("Compute returned: %f\n", ret.f32);
2.6 错误处理与异常捕获
LeanCLR 提供了异常捕获机制,防止 C# 侧的未处理异常导致宿主崩溃:
// 设置异常回调
void OnUnhandledException(leanclr_runtime* rt,
const char* message,
void* user_data) {
fprintf(stderr, "C# exception: %s\n", message);
}
leanclr_set_exception_handler(rt, OnUnhandledException, NULL);
// 在调用点检查错误码
leanclr_value result;
int ec = leanclr_execute_static(
rt, "MyApp.RiskyModule",
"DoWork", 0, NULL, &result
);
if (ec != LEANCLR_OK) {
// 获取错误详情
const char* err = leanclr_get_last_error(rt);
printf("Execution failed: %s\n", err);
}
2.7 内存管理注意事项
LeanCLR 的 GC 与宿主内存空间是分离的。跨边界传递对象时,需要注意生命周期管理。建议使用值类型或基本数据类型进行频繁的跨边界通信,减少 GC 压力。
当从 C# 侧向宿主传递字符串或数组时,LeanCLR 会返回托管堆内存的指针,宿主需要在当前帧内完成数据拷贝,否则 GC 回收后指针会失效。推荐的模式是立即将数据复制到宿主管理的缓冲区中:
// 安全读取 C# 字符串的示例
const char* managed_str = leanclr_string_get(rt, obj_value);
char local_buf[256];
strncpy(local_buf, managed_str, sizeof(local_buf) - 1);
local_buf[sizeof(local_buf) - 1] = '\0';
// 从现在开始使用 local_buf,managed_str 随时可能失效
三、LeanCLR 的高级特性
3.1 热更新机制
LeanCLR 支持运行时的程序集热重载,无需重启进程即可更新业务逻辑。这在游戏运营、服务端热修复等场景中至关重要:
// 热更新工作流
void HotReloadAssembly(leanclr_runtime* rt, const char* path) {
// 1. 卸载旧版本程序集
leanclr_unload_assembly(rt, "MyApp.dll");
// 2. 加载新版本程序集
leanclr_load_assembly_file(rt, path);
// 3. 重新执行入口点
leanclr_value result;
leanclr_execute_static(
rt, "MyApp.Program",
"Main", 0, NULL, &result
);
}
热更新的核心要点在于保证状态迁移的正确性——旧版本创建的对象的生命周期需要妥善管理,建议在新版本加载后重置所有相关状态。此外,如果热更新涉及全局静态变量的修改,也需要在卸载旧程序集之前保存并恢复关键状态,以避免状态丢失导致运行时异常。
3.2 热修复脚本
在线上紧急修复场景中,可以通过热修复脚本快速修补逻辑,无需重新构建宿主应用。热修复脚本作为独立的程序集加载,在运行时替换原有方法的行为:
// 运行时加载的热修复脚本
public static class HotfixPatches
{
public static int FixedAdd(int a, int b)
{
// 原始代码:return a + b;
// 热修复:处理整数溢出
try {
checked { return a + b; }
} catch (OverflowException) {
return a > 0 ? int.MaxValue : int.MinValue;
}
}
}
配合 LeanCLR 的方法替换 API,可以将 Calculator.Add 动态替换为 HotfixPatches.FixedAdd。这种模式与第 35-37 篇中讨论的 HybridCLR 热修复机制原理相通。
热修复脚本的部署流程如下:首先将修复后的 C# 代码编译为独立程序集,通过资产管理平台下发到客户端或服务器。宿主应用监听更新通知,收到后调用 leanclr_load_assembly_file 加载补丁程序集,然后通过 leanclr_replace_method 将目标方法替换为补丁方法。整个过程无需重启应用,用户无感知。
3.3 性能调优
LeanCLR 的解释执行天然比原生代码慢,但通过以下优化手段可以大幅缩小差距。在实际项目中,综合运用这些技术通常可以将性能提升到满足生产需求的水平:
AOT 预编译热点路径:选择帧循环、碰撞检测、网络协议解析等 CPU 密集的方法进行预编译,可以将其执行速度从解释模式的 30-50% 原生提升到接近原生水平:
// 预编译频繁调用的方法,提升执行速度
leanclr_aot_compile(rt, "GameLogic", "Update");
leanclr_aot_compile(rt, "PhysicsEngine", "Simulate");
对象池降低 GC 压力:C# 中频繁创建和销毁对象会产生大量 GC 压力,对象池模式可以有效缓解此问题。对于每帧创建大量临时对象的热点路径,建议实现对象池来复用实例,将 GC 触发频率从每秒数十次降低到几秒一次。
减少跨边界调用:宿主与托管域之间的每次调用都有额外开销(参数封送、上下文切换、GC 句柄保护),应尽量合并批量操作而非逐次调用。例如将 100 次单属性访问合并为一次批量数据交换。
优先使用静态方法:虚方法分发在解释执行中有额外成本,热点路径上尽量使用静态方法替代。
3.5 诊断与性能分析
量化分析是性能调优的前提。LeanCLR 提供了内置的诊断接口:
// 启用性能计数器
leanclr_enable_counters(rt, true);
// 在执行关键路径前后获取统计数据
leanclr_stats before = leanclr_get_stats(rt);
// ... 执行待测逻辑 ...
leanclr_stats after = leanclr_get_stats(rt);
// 计算差值
uint64_t interpreted_calls = after.interpreted_calls - before.interpreted_calls;
uint64_t aot_calls = after.aot_calls - before.aot_calls;
double elapsed_ms = (after.total_ticks - before.total_ticks) / 1000.0;
printf("Interpreted calls: %llu\n", interpreted_calls);
printf("AOT calls: %llu\n", aot_calls);
printf("Elapsed: %.2f ms\n", elapsed_ms);
通过这些数据,你可以精确识别哪些方法处于热点路径、解释执行的开销占比,从而有针对性地应用 AOT 预编译或其他优化手段。
性能优化手段对比表:
| 优化手段 | 提升幅度 | 适用场景 | 代价 |
|---|---|---|---|
| AOT 预编译 | 2x–5x | 热点循环函数 | 增加二进制体积 |
| 对象池 | 减少 GC 50–80% | 频繁创建销毁的对象 | 编码复杂度 |
| 合并宿主调用 | 减少 30–50% 开销 | 频繁 C++/C# 交互 | 架构调整 |
| 内联小函数 | 减少 10–20% | 频繁调用的 getter/setter | 可读性降低 |
3.4 与 HybridCLR 的脚本复用
LeanCLR 和 HybridCLR 使用相同的 C# 语法和 .NET 中间表示,因此业务逻辑代码可以在两个运行时之间无缝复用:
// 共享业务逻辑 —— 同时在 HybridCLR 和 LeanCLR 中运行
public static class GameLogicShared
{
public static int ComputeDamage(int baseAtk, int def, float multiplier)
{
float raw = (baseAtk - def * 0.5f) * multiplier;
return Math.Max(1, (int)raw);
}
}
采用"一次编译,两处运行"的策略:在 Unity 环境中通过 HybridCLR 加载这段代码,在独立服务器或工具链中通过 LeanCLR 加载。这种交叉复用能力在项目架构层面提供了极大的灵活性,实现了游戏客户端热更新逻辑与服务端校验逻辑的代码统一,减少了维护成本。有关详细策略可参考第 10 章(HybridCLR 实战指南)。
3.6 实际部署中的注意事项
将 LeanCLR 集成到生产环境时,还需要关注以下几个关键方面:
程序集版本管理:采用语义化版本号标记每个已部署的程序集,并在加载时校验版本信息。建议在 C# 程序集中嵌入 AssemblyVersion 和 AssemblyFileVersion 属性,宿主在加载时读取并与预期版本对比,避免版本错配导致的运行时错误。
日志与监控集成:将 LeanCLR 的诊断输出接入项目的统一日志系统。可以通过 leanclr_set_log_callback 注册日志回调,将运行时内部的告警和信息直接转发到现有的日志管道。这对线上问题的快速定位至关重要。
安全沙箱:如果 LeanCLR 用于执行用户提交的代码(如 Mod 系统或脚本扩展),需要建立安全沙箱机制。限制程序集可访问的 API 范围,在宿主层对敏感操作进行权限检查,避免恶意代码通过反射调用系统级 API。例如,可以通过白名单机制只允许访问特定的命名空间和方法。
四、常见问题与排查
4.1 编译问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| undefined reference to leanclr_* | 未链接库文件 | 在 CMakeLists.txt 中添加 target_link_libraries |
| emcmake not found | Emscripten 未初始化 | 执行 source emsdk_env.sh 初始化环境 |
| C# compilation error | .NET SDK 版本不匹配 | 使用 .NET Standard 2.0 目标框架,确保兼容性 |
| DLL load failed | 程序集格式错误 | 使用 ilasm 或 peverify 检查程序集完整性 |
| link error: unresolved external symbol | 函数签名不匹配 | 检查 C++ 编译选项是否与 LeanCLR 库一致(如异常模型、结构体对齐) |
| wasm-ld error: initial memory too small | WASM 内存配置不足 | 添加 -s INITIAL_MEMORY=64MB 编译参数 |
4.2 运行时问题
以下是在 LeanCLR 实际使用中遇到频率最高的运行时问题:
"Assembly not found":检查文件路径是否正确,以及 leanclr_load_assembly_file 调用时程序集是否已生成到目标目录。
"Method not found":检查类型名和方法名的拼写及大小写。C# 是大小写敏感的,注意命名空间前缀是否完整。
"Type load exception":类型依赖的其他程序集尚未加载。务必按照依赖顺序加载程序集——先加载被依赖的库,再加载依赖方。
"Out of memory":内存不足。增大 memory_limit 配置项,或检查是否存在内存泄漏(例如未释放的跨边界对象)。
"Stack overflow":递归层数过深。增大解释器的栈大小配置,或优化递归逻辑转为迭代实现。对于深度优先搜索等天然递归算法,建议在 C# 侧就转换为显式栈迭代。
"Access violation":跨边界传递的指针已失效。检查是否在 GC 回收后继续使用托管对象指针,确保在帧内完成数据拷贝。
"Entry point not found":程序集中不存在指定的入口方法。使用 leanclr_enum_methods 枚举程序集中的所有方法以确认正确的方法签名。
"Metadata corruption":程序集文件被损坏或版本不兼容。重新编译 C# 源码生成程序集,或检查不同 .NET 运行时版本之间的兼容性。
运行时崩溃无明确错误信息:启用地址清理器(AddressSanitizer)构建 LeanCLR 以捕获内存错误。在构建时添加 -DCMAKE_CXX_FLAGS="-fsanitize=address" 重新编译,运行复现场景即可获得精确的内存错误定位。
4.3 调试技巧
LeanCLR 不提供像 Visual Studio 那样完整的托管调试器,但可以通过以下手段有效排查问题。这些方法在生产环境紧急排障时同样适用:
详细日志模式:在创建运行时配置时启用详细日志:
cfg.log_level = LEANCLR_LOG_VERBOSE;
cfg.log_callback = MyLogCallback;
详细模式下,运行时会在关键节点(程序集加载、方法解析、GC 触发)输出日志信息,帮助定位问题来源。建议在开发测试阶段始终开启详细日志,上线前调整为 ERROR 级别以减少日志输出量。
方法枚举验证:当遇到"Method not found"错误时,枚举程序集中的所有方法确认签名:
leanclr_enum_methods(rt, "MyApp.Program",
[](const char* name, const char* sig, void*) {
printf(" %s : %s\n", name, sig);
return true;
}, NULL);
分步加载测试:将加载和调用拆分为独立步骤,逐一验证每个环节的返回值。先验证程序集加载成功,再验证类型存在,最后验证方法可调用。
4.4 平台兼容性问题
不同平台对 .NET 功能子集的支持程度不同,需要特别关注以下差异:
- WebAssembly (WASM):不支持
System.Threading,仅单线程模式运行。所有涉及线程同步的代码需要进行改造或移除。 - ARM 嵌入式设备:注意二进制序列化时的端序(endianness)问题——ARM 支持大端和小端,确保序列化数据的字节序与目标一致。
- Windows (MSVC 构建):依赖 VC++ 可再发行组件包(Visual C++ Redistributable),部署时需确保目标环境已安装该组件。
- Linux (glibc):部分高级特性需要 glibc ≥ 2.28,较老的操作系统(如 CentOS 7)可能需要升级 glibc 或使用静态链接。
总结
本文从环境搭建出发,详细介绍了 LeanCLR 的基本使用方法,包括程序集加载、C# 代码执行、宿主交互,以及热更新、热修复、性能调优等高级特性,最后给出了常见问题的排查方案。通过本文的学习,读者应该能够独立完成 LeanCLR 的集成工作——从下载源码编译到在生产环境中部署运行,涵盖了完整的工作流程。
LeanCLR 的核心价值在于让 C# 真正实现"一处编写,随处运行"——从浏览器 WebAssembly 到嵌入式设备,从 Unity 游戏到独立服务器应用,C# 生态的力量得以充分释放。本文中涉及的实战技能(环境搭建、程序集加载、宿主交互、热更新、性能调优)可直接迁移到实际项目中。
建议读者将本文与第 38 篇(生态概览)、第 39 篇(架构解析)、第 40 篇(源码剖析)对照阅读,形成系统性的理解。热修复相关机制可参考第 35-37 篇(HybridCLR 热修复专题),完整项目实践可参阅第 10 章(HybridCLR 实战指南)。
回顾 LeanCLR 的发展历程,这个项目从最初的概念验证到如今的生产可用,展示了 .NET 运行时精简化的巨大潜力。随着 WebAssembly 和边缘计算的持续发展,像 LeanCLR 这样的轻量级运行时将在更多场景中发挥作用。掌握 LeanCLR 不仅意味着多了一种技术选型,更意味着对 CLR 运行时本质有了更深层的理解——这正是贯穿本系列文章的核心目标。在下一章(第 10 章·实战篇-从零搭建)中,我们将回到 Unity 环境,利用 HybridCLR 完成一个完整的项目实战。
参考资源
- LeanCLR GitHub 仓库 — GitHub - focus-creative-games/leanclr: LeanCLR is a production-oriented CLR implementation. Its core goal is to provide high ECMA-335 compatibility, low integration complexity, and strong cross-platform capability, so developers can truly achieve “Write C#, Run Anywhere.” · GitHub
- LeanCLR 构建文档 — 仓库内 docs/BUILD.md
- LeanCLR 示例项目 — 仓库内 samples/ 目录
- CMake 官方文档 — CMake Documentation and Community
- Emscripten SDK 安装指南 — Download and install - Emscripten 6.0.1-git (dev) documentation
- 第 38 篇:LeanCLR 生态概览(09-生态篇-LeanCLR)
- 第 39 篇:LeanCLR 架构解析(09-生态篇-LeanCLR)
- 第 40 篇:LeanCLR 源码剖析(09-生态篇-LeanCLR)
- 第 35-37 篇:HybridCLR 热修复专题(08-核心技术-热重载与热修复)
- 第 10 章:HybridCLR 实战指南