【m】hybrid更新为8.11.0
All checks were successful
Plugin Library CI / publish (00.BuildOriginality) (push) Successful in 3s
Plugin Library CI / publish (00.StaryEvo) (push) Successful in 5s
Plugin Library CI / publish (00.StaryEvoTools) (push) Successful in 10s
Plugin Library CI / publish (01.HybridCLR) (push) Successful in 8s
Plugin Library CI / publish (02.InformationSave) (push) Successful in 3s
Plugin Library CI / publish (03.YooAsset) (push) Successful in 34s
Plugin Library CI / publish (04.AudioCore) (push) Successful in 2s
Plugin Library CI / publish (05.TableTextConversion) (push) Successful in 5s
Plugin Library CI / publish (06.UIFarme) (push) Successful in 17s
Plugin Library CI / publish (07.RKTools) (push) Successful in 4s
Plugin Library CI / publish (08.UniTask) (push) Successful in 3s
Plugin Library CI / publish (09.CodeChecker) (push) Successful in 17s
Plugin Library CI / publish (10.StoryEditor) (push) Successful in 3s
Plugin Library CI / publish (10.XNode) (push) Successful in 4s
Plugin Library CI / publish (11.PointCloudTools) (push) Successful in 3s

This commit is contained in:
2026-04-13 22:59:23 +08:00
parent a7902e8224
commit a441a06257
20 changed files with 335 additions and 121 deletions

View File

@@ -2,38 +2,43 @@
"versions": [ "versions": [
{ {
"unity_version":"2019", "unity_version":"2019",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v2019-8.1.0"} "il2cpp_plus": { "branch":"v2019-8.9.0"}
}, },
{ {
"unity_version":"2020", "unity_version":"2020",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v2020-8.1.0"} "il2cpp_plus": { "branch":"v2020-8.9.0"}
}, },
{ {
"unity_version":"2021", "unity_version":"2021",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v2021-8.1.0"} "il2cpp_plus": { "branch":"v2021-8.1.0"}
}, },
{ {
"unity_version":"2022", "unity_version":"2022",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v2022-8.2.0"} "il2cpp_plus": { "branch":"v2022-8.11.0"}
}, },
{ {
"unity_version":"2022-tuanjie", "unity_version":"2022-tuanjie",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v2022-tuanjie-8.1.0"} "il2cpp_plus": { "branch":"v2022-tuanjie-8.11.0"}
}, },
{ {
"unity_version":"2023", "unity_version":"2023",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v2023-8.1.0"} "il2cpp_plus": { "branch":"v2023-8.1.0"}
}, },
{ {
"unity_version":"6000", "unity_version":"6000",
"hybridclr" : { "branch":"v8.2.0"}, "hybridclr" : { "branch":"v8.11.0"},
"il2cpp_plus": { "branch":"v6000-8.1.0"} "il2cpp_plus": { "branch":"v6000-8.11.0"}
},
{
"unity_version":"6000.3.x",
"hybridclr" : { "branch":"v6000.3.x-8.11.0"},
"il2cpp_plus": { "branch":"v6000.3.x-8.11.0"}
} }
] ]
} }

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.ABI
{
public static class ABIUtil
{
public static string GetHybridCLRPlatformMacro(PlatformABI abi)
{
switch(abi)
{
case PlatformABI.Arm64: return "HYBRIDCLR_ABI_ARM_64";
case PlatformABI.Universal64: return "HYBRIDCLR_ABI_UNIVERSAL_64";
case PlatformABI.Universal32: return "HYBRIDCLR_ABI_UNIVERSAL_32";
case PlatformABI.WebGL32: return "HYBRIDCLR_ABI_WEBGL32";
default: throw new NotSupportedException();
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: edeb86f4b5b13ca4cb0fe9d87ce509bb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -46,12 +46,21 @@ namespace HybridCLR.Editor.BuildProcessors
return; return;
} }
BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
#if UNITY_6000_0_OR_NEWER
NamedBuildTarget namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup);
ScriptingImplementation curScriptingImplementation = PlayerSettings.GetScriptingBackend(namedBuildTarget);
#else
ScriptingImplementation curScriptingImplementation = PlayerSettings.GetScriptingBackend(buildTargetGroup); ScriptingImplementation curScriptingImplementation = PlayerSettings.GetScriptingBackend(buildTargetGroup);
#endif
ScriptingImplementation targetScriptingImplementation = ScriptingImplementation.IL2CPP; ScriptingImplementation targetScriptingImplementation = ScriptingImplementation.IL2CPP;
if (curScriptingImplementation != targetScriptingImplementation) if (curScriptingImplementation != targetScriptingImplementation)
{ {
Debug.LogError($"[CheckSettings] current ScriptingBackend:{curScriptingImplementation}have been switched to:{targetScriptingImplementation} automatically"); Debug.LogError($"[CheckSettings] current ScriptingBackend:{curScriptingImplementation}have been switched to:{targetScriptingImplementation} automatically");
#if UNITY_6000_0_OR_NEWER
PlayerSettings.SetScriptingBackend(namedBuildTarget, targetScriptingImplementation);
#else
PlayerSettings.SetScriptingBackend(buildTargetGroup, targetScriptingImplementation); PlayerSettings.SetScriptingBackend(buildTargetGroup, targetScriptingImplementation);
#endif
} }
var installer = new Installer.InstallerController(); var installer = new Installer.InstallerController();

View File

@@ -64,6 +64,9 @@ namespace HybridCLR.Editor.BuildProcessors
return $"{projectDir}/Library/Bee/artifacts/PS4PlayerBuildProgram/ManagedStripped"; return $"{projectDir}/Library/Bee/artifacts/PS4PlayerBuildProgram/ManagedStripped";
case BuildTarget.PS5: case BuildTarget.PS5:
return $"{projectDir}/Library/Bee/artifacts/PS5PlayerBuildProgram/ManagedStripped"; return $"{projectDir}/Library/Bee/artifacts/PS5PlayerBuildProgram/ManagedStripped";
case BuildTarget.GameCoreXboxOne:
case BuildTarget.GameCoreXboxSeries:
return $"{projectDir}/Library/Bee/artifacts/GameCorePlayerBuildProgram/ManagedStripped";
#if UNITY_WEIXINMINIGAME #if UNITY_WEIXINMINIGAME
case BuildTarget.WeixinMiniGame: case BuildTarget.WeixinMiniGame:
return $"{projectDir}/Library/Bee/artifacts/WeixinMiniGame/ManagedStripped"; return $"{projectDir}/Library/Bee/artifacts/WeixinMiniGame/ManagedStripped";

View File

@@ -9,7 +9,6 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using static UnityEngine.Networking.UnityWebRequest;
namespace HybridCLR.Editor.Commands namespace HybridCLR.Editor.Commands
{ {
@@ -136,8 +135,8 @@ namespace HybridCLR.Editor.Commands
options = buildOptions, options = buildOptions,
target = target, target = target,
targetGroup = BuildPipeline.GetBuildTargetGroup(target), targetGroup = BuildPipeline.GetBuildTargetGroup(target),
#if UNITY_2021_1_OR_NEWER #if UNITY_SERVER
subtarget = (int)EditorUserBuildSettings.standaloneBuildSubtarget, subtarget = (int)StandaloneBuildSubtarget.Server,
#endif #endif
}; };

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 9343e3f36d5deca4880d49f48b3fa2b1 guid: 2373f786d14518f44b0f475db77ba4de
AssemblyDefinitionImporter: AssemblyDefinitionImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@@ -102,42 +102,23 @@ namespace HybridCLR.Editor.Installer
} }
Directory.CreateDirectory(dir); Directory.CreateDirectory(dir);
} }
private static void CopyWithCheckLongFile(string srcFile, string dstFile)
{
var maxPathLength = 255;
#if UNITY_EDITOR_OSX
maxPathLength = 1024;
#endif
if (srcFile.Length > maxPathLength)
{
UnityEngine.Debug.LogError($"srcFile:{srcFile} path is too long. skip copy!");
return;
}
if (dstFile.Length > maxPathLength)
{
UnityEngine.Debug.LogError($"dstFile:{dstFile} path is too long. skip copy!");
return;
}
File.Copy(srcFile, dstFile);
}
public static void CopyDir(string src, string dst, bool log = false) public static void CopyDir(string src, string dst, bool log = false)
{ {
if (log) if (log)
{ {
UnityEngine.Debug.Log($"[BashUtil] CopyDir {src} => {dst}"); UnityEngine.Debug.Log($"[BashUtil] CopyDir {src} => {dst}");
} }
if (Directory.Exists(dst))
{
RemoveDir(dst); RemoveDir(dst);
Directory.CreateDirectory(dst); }
foreach(var file in Directory.GetFiles(src)) else
{ {
CopyWithCheckLongFile(file, $"{dst}/{Path.GetFileName(file)}"); string parentDir = Path.GetDirectoryName(Path.GetFullPath(dst));
} Directory.CreateDirectory(parentDir);
foreach(var subDir in Directory.GetDirectories(src))
{
CopyDir(subDir, $"{dst}/{Path.GetFileName(subDir)}");
} }
UnityEditor.FileUtil.CopyFileOrDirectory(src, dst);
} }
} }
} }

View File

@@ -1,3 +1,6 @@
#if UNITY_6000_3_OR_NEWER && UNITY_EDITOR_OSX
#define NEW_IL2CPP_PATH
#endif
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -8,6 +11,7 @@ using Debug = UnityEngine.Debug;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq; using System.Linq;
using HybridCLR.Editor.Settings; using HybridCLR.Editor.Settings;
using System.Runtime.InteropServices;
namespace HybridCLR.Editor.Installer namespace HybridCLR.Editor.Installer
{ {
@@ -33,7 +37,15 @@ namespace HybridCLR.Editor.Installer
{ {
_curVersion = ParseUnityVersion(Application.unityVersion); _curVersion = ParseUnityVersion(Application.unityVersion);
_versionManifest = GetHybridCLRVersionManifest(); _versionManifest = GetHybridCLRVersionManifest();
_curDefaultVersion = _versionManifest.versions.FirstOrDefault(v => _curVersion.isTuanjieEngine ? v.unity_version == $"{_curVersion.major}-tuanjie" : v.unity_version == _curVersion.major.ToString()); _curDefaultVersion = _versionManifest.versions.FirstOrDefault(v => {
return _curVersion.isTuanjieEngine? v.unity_version == $"{_curVersion.major}-tuanjie"
#if UNITY_6000_3_OR_NEWER
: v.unity_version == "6000.3.x"
#else
: v.unity_version == _curVersion.major.ToString()
#endif
;
});
PackageVersion = LoadPackageInfo().version; PackageVersion = LoadPackageInfo().version;
InstalledLibil2cppVersion = ReadLocalVersion(); InstalledLibil2cppVersion = ReadLocalVersion();
} }
@@ -127,7 +139,11 @@ namespace HybridCLR.Editor.Installer
case 2021: return "2021.3.0"; case 2021: return "2021.3.0";
case 2022: return "2022.3.0"; case 2022: return "2022.3.0";
case 2023: return "2023.2.0"; case 2023: return "2023.2.0";
#if UNITY_6000_3_OR_NEWER
case 6000: return "6000.3.0";
#else
case 6000: return "6000.0.0"; case 6000: return "6000.0.0";
#endif
default: return $"2020.3.0"; default: return $"2020.3.0";
} }
} }
@@ -158,13 +174,27 @@ namespace HybridCLR.Editor.Installer
public string Il2cppPlusLocalVersion => _curDefaultVersion?.il2cpp_plus?.branch; public string Il2cppPlusLocalVersion => _curDefaultVersion?.il2cpp_plus?.branch;
public string ApplicationIl2cppPath
private string GetIl2CppPathByContentPath(string contentPath)
{ {
return $"{contentPath}/il2cpp"; get
{
Debug.Log($"application path:{EditorApplication.applicationPath} {EditorApplication.applicationContentsPath}");
#if NEW_IL2CPP_PATH
#if UNITY_IOS
string platformDirName = "iOSSupport";
#elif UNITY_TVOS
string platformDirName = "AppleTVSupport";
#elif UNITY_VISIONOS
string platformDirName = "VisionOSPlayer";
#else
string platformDirName = "iOSSupport";
#endif
return $"{EditorApplication.applicationContentsPath}/../../PlaybackEngines/{platformDirName}/il2cpp";
#else
return $"{EditorApplication.applicationContentsPath}/il2cpp";
#endif
}
} }
public string ApplicationIl2cppPath => GetIl2CppPathByContentPath(EditorApplication.applicationContentsPath);
public string LocalVersionFile => $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/generated/libil2cpp-version.txt"; public string LocalVersionFile => $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/generated/libil2cpp-version.txt";
@@ -266,12 +296,23 @@ namespace HybridCLR.Editor.Installer
// create LocalIl2Cpp // create LocalIl2Cpp
string localUnityDataDir = SettingsUtil.LocalUnityDataDir; string localUnityDataDir = SettingsUtil.LocalUnityDataDir;
BashUtil.RecreateDir(localUnityDataDir); BashUtil.RecreateDir(localUnityDataDir);
#if !NEW_IL2CPP_PATH
// copy MonoBleedingEdge // copy MonoBleedingEdge
BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true); BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
#endif
// copy il2cpp // copy il2cpp
BashUtil.CopyDir(editorIl2cppPath, SettingsUtil.LocalIl2CppDir, true); BashUtil.CopyDir(editorIl2cppPath, SettingsUtil.LocalIl2CppDir, true);
#if NEW_IL2CPP_PATH
string buildDir = $"{SettingsUtil.LocalIl2CppDir}/build";
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm || RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
BashUtil.CopyDir($"{buildDir}/deploy_arm64", $"{buildDir}/deploy", false);
}
else
{
BashUtil.CopyDir($"{buildDir}/deploy_x86_64", $"{buildDir}/deploy", false);
}
#endif
// replace libil2cpp // replace libil2cpp
string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp"; string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";

View File

@@ -5,5 +5,7 @@ namespace HybridCLR.Editor.MethodBridge
public class CallNativeMethodSignatureInfo public class CallNativeMethodSignatureInfo
{ {
public MethodSig MethodSig { get; set; } public MethodSig MethodSig { get; set; }
public CallingConvention? Callvention { get; set; }
} }
} }

View File

@@ -287,6 +287,7 @@ namespace HybridCLR.Editor.MethodBridge
CollectStructDefs(_managed2NativeMethodList0, structTypeSet); CollectStructDefs(_managed2NativeMethodList0, structTypeSet);
CollectStructDefs(_native2ManagedMethodList0, structTypeSet); CollectStructDefs(_native2ManagedMethodList0, structTypeSet);
CollectStructDefs(_adjustThunkMethodList0, structTypeSet); CollectStructDefs(_adjustThunkMethodList0, structTypeSet);
CollectStructDefs(_originalCalliMethodSignatures.Select(m => m.MethodSig).ToList(), structTypeSet);
_structTypes0 = structTypeSet.ToList(); _structTypes0 = structTypeSet.ToList();
_structTypes0.Sort((a, b) => a.TypeId - b.TypeId); _structTypes0.Sort((a, b) => a.TypeId - b.TypeId);
@@ -558,6 +559,11 @@ namespace HybridCLR.Editor.MethodBridge
{ {
return CallingConvention.Winapi; return CallingConvention.Winapi;
} }
if (monoPInvokeCallbackAttr.ConstructorArguments.Count == 0)
{
Debug.LogError($"MonoPInvokeCallbackAttribute on method {method.FullName} has no constructor arguments. Using CallingConvention.Winapi as default.");
return CallingConvention.Winapi;
}
object delegateTypeSig = monoPInvokeCallbackAttr.ConstructorArguments[0].Value; object delegateTypeSig = monoPInvokeCallbackAttr.ConstructorArguments[0].Value;
TypeDef delegateTypeDef; TypeDef delegateTypeDef;
@@ -579,7 +585,7 @@ namespace HybridCLR.Editor.MethodBridge
throw new NotSupportedException($"Unsupported delegate type: {delegateTypeSig}"); throw new NotSupportedException($"Unsupported delegate type: {delegateTypeSig}");
} }
var attr = delegateTypeDef.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute"); var attr = delegateTypeDef.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute");
if (attr == null) if (attr == null || attr.ConstructorArguments.Count == 0)
{ {
return CallingConvention.Winapi; return CallingConvention.Winapi;
} }
@@ -637,7 +643,7 @@ namespace HybridCLR.Editor.MethodBridge
sharedMethod.Init(); sharedMethod.Init();
sharedMethod = ToIsomorphicMethod(sharedMethod); sharedMethod = ToIsomorphicMethod(sharedMethod);
CallingConvention callingConv = (CallingConvention)((int)(method.MethodSig.CallingConvention & dnlib.DotNet.CallingConvention.Mask) + 1); CallingConvention callingConv = (CallingConvention)((int)((method.Callvention ?? method.MethodSig.CallingConvention) & dnlib.DotNet.CallingConvention.Mask) + 1);
string signature = MakeCalliSignature(sharedMethod, callingConv); string signature = MakeCalliSignature(sharedMethod, callingConv);
if (!methodsBySig.TryGetValue(signature, out var arm)) if (!methodsBySig.TryGetValue(signature, out var arm))
@@ -829,6 +835,38 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
} }
private void CollectStructDefs(List<MethodSig> methods, HashSet<TypeInfo> structTypes)
{
ICorLibTypes corLibTypes = _genericMethods[0].Method.Module.CorLibTypes;
foreach (var method in methods)
{
foreach (var paramInfo in method.Params)
{
var paramType = GetSharedTypeInfo(MetaUtil.ToShareTypeSig(corLibTypes, paramInfo));
if (paramType.IsStruct)
{
structTypes.Add(paramType);
if (paramType.Klass.ContainsGenericParameter)
{
throw new Exception($"[CollectStructDefs] method:{method} type:{paramType.Klass} contains generic parameter");
}
}
}
var returnType = GetSharedTypeInfo(MetaUtil.ToShareTypeSig(corLibTypes, method.RetType));
if (returnType.IsStruct)
{
structTypes.Add(returnType);
if (returnType.Klass.ContainsGenericParameter)
{
throw new Exception($"[CollectStructDefs] method:{method} type:{returnType.Klass} contains generic parameter");
}
}
}
}
class FieldInfo class FieldInfo
{ {
public FieldDef field; public FieldDef field;

View File

@@ -3,6 +3,7 @@ using HybridCLR.Editor.Meta;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
@@ -26,6 +27,19 @@ namespace HybridCLR.Editor.MethodBridge
} }
} }
private CallingConvention GetCallingConvention(MethodDef method)
{
switch (method.ImplMap.CallConv)
{
case PInvokeAttributes.CallConvWinapi: return CallingConvention.Default;
case PInvokeAttributes.CallConvCdecl: return CallingConvention.C;
case PInvokeAttributes.CallConvStdCall: return CallingConvention.StdCall;
case PInvokeAttributes.CallConvThiscall: return CallingConvention.ThisCall;
case PInvokeAttributes.CallConvFastcall: return CallingConvention.FastCall;
default: return CallingConvention.Default;
}
}
public void Run() public void Run()
{ {
foreach (var mod in _rootModules) foreach (var mod in _rootModules)
@@ -40,7 +54,11 @@ namespace HybridCLR.Editor.MethodBridge
{ {
Debug.LogError($"PInvoke method {method.FullName} has unsupported parameter or return type. Please check the method signature."); Debug.LogError($"PInvoke method {method.FullName} has unsupported parameter or return type. Please check the method signature.");
} }
_pinvokeMethodSignatures.Add(new CallNativeMethodSignatureInfo { MethodSig = method.MethodSig }); _pinvokeMethodSignatures.Add(new CallNativeMethodSignatureInfo
{
MethodSig = method.MethodSig,
Callvention = method.HasImplMap? GetCallingConvention(method) : (CallingConvention?)null,
});
} }
} }
} }

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 259c1cb7fe681f74eb435ab8f268890d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -8,7 +8,7 @@ namespace HybridCLR.Editor.Settings
{ {
[MenuItem("HybridCLR/About", priority = 0)] [MenuItem("HybridCLR/About", priority = 0)]
public static void OpenAbout() => Application.OpenURL("https://hybridclr.doc.code-philosophy.com/docs/intro"); public static void OpenAbout() => Application.OpenURL("https://www.hybridclr.cn/docs/intro");
[MenuItem("HybridCLR/Installer...", priority = 60)] [MenuItem("HybridCLR/Installer...", priority = 60)]
private static void Open() private static void Open()
@@ -21,19 +21,19 @@ namespace HybridCLR.Editor.Settings
public static void OpenSettings() => SettingsService.OpenProjectSettings("Project/HybridCLR Settings"); public static void OpenSettings() => SettingsService.OpenProjectSettings("Project/HybridCLR Settings");
[MenuItem("HybridCLR/Documents/Quick Start")] [MenuItem("HybridCLR/Documents/Quick Start")]
public static void OpenQuickStart() => Application.OpenURL("https://hybridclr.doc.code-philosophy.com/docs/beginner/quickstart"); public static void OpenQuickStart() => Application.OpenURL("https://www.hybridclr.cn/docs/beginner/quickstart");
[MenuItem("HybridCLR/Documents/Performance")] [MenuItem("HybridCLR/Documents/Performance")]
public static void OpenPerformance() => Application.OpenURL("https://hybridclr.doc.code-philosophy.com/docs/basic/performance"); public static void OpenPerformance() => Application.OpenURL("https://www.hybridclr.cn/docs/basic/performance");
[MenuItem("HybridCLR/Documents/FAQ")] [MenuItem("HybridCLR/Documents/FAQ")]
public static void OpenFAQ() => Application.OpenURL("https://hybridclr.doc.code-philosophy.com/docs/help/faq"); public static void OpenFAQ() => Application.OpenURL("https://www.hybridclr.cn/docs/help/faq");
[MenuItem("HybridCLR/Documents/Common Errors")] [MenuItem("HybridCLR/Documents/Common Errors")]
public static void OpenCommonErrors() => Application.OpenURL("https://hybridclr.doc.code-philosophy.com/docs/help/commonerrors"); public static void OpenCommonErrors() => Application.OpenURL("https://www.hybridclr.cn/docs/help/commonerrors");
[MenuItem("HybridCLR/Documents/Bug Report")] [MenuItem("HybridCLR/Documents/Bug Report")]
public static void OpenBugReport() => Application.OpenURL("https://hybridclr.doc.code-philosophy.com/docs/help/issue"); public static void OpenBugReport() => Application.OpenURL("https://www.hybridclr.cn/docs/help/issue");
} }
} }

View File

@@ -21,18 +21,19 @@ HybridCLR扩充了il2cpp运行时代码使它由纯[AOT](https://en.wikipedia
## 文档 ## 文档
- [官方文档](https://hybridclr.doc.code-philosophy.com/docs/intro) - [官方文档](https://www.hybridclr.cn/docs/intro)
- [快速上手](https://hybridclr.doc.code-philosophy.com/docs/beginner/quickstart) - [快速上手](https://www.hybridclr.cn/docs/beginner/quickstart)
- [商业项目案例](https://hybridclr.doc.code-philosophy.com/docs/other/businesscase) - [商业项目案例](https://www.hybridclr.cn/docs/other/businesscase)
- [LeanCLR](https://github.com/focus-creative-games/leanclr)
## 特性 ## 特性
- 近乎完整实现了[ECMA-335规范](https://www.ecma-international.org/publications-and-standards/standards/ecma-335/),只有极少量的[不支持的特性](https://hybridclr.doc.code-philosophy.com/docs/basic/notsupportedfeatures)。 - 近乎完整实现了[ECMA-335规范](https://www.ecma-international.org/publications-and-standards/standards/ecma-335/),只有极少量的[不支持的特性](https://www.hybridclr.cn/docs/basic/notsupportedfeatures)。
- 零学习和使用成本。对绝大多数开发者来说写代码近乎没有限制。 热更新代码与AOT代码无缝工作可以随意写继承、**泛型**、**反射**之类的代码。不需要额外写任何特殊代码、没有代码生成 - 零学习和使用成本。对绝大多数开发者来说写代码近乎没有限制。 热更新代码与AOT代码无缝工作可以随意写继承、**泛型**、**反射**之类的代码。不需要额外写任何特殊代码、没有代码生成
- 完全支持多线程,包含但不限于 volatile、ThreadStatic、async Task等相关功能和特性。这是其他所有热更新方案都不支持的 - 完全支持多线程,包含但不限于 volatile、ThreadStatic、async Task等相关功能和特性。这是其他所有热更新方案都不支持的
- 几乎完全兼容Unity的工作流。包括且不限于支持热更新**MonoBehaviour**、ScriptableObject、**DOTS**技术,资源上挂载的热更新脚本可以正确实例化,这是其他所有热更新方案都不支持的 - 几乎完全兼容Unity的工作流。包括且不限于支持热更新**MonoBehaviour**、ScriptableObject、**DOTS**技术,资源上挂载的热更新脚本可以正确实例化,这是其他所有热更新方案都不支持的
- 执行高效。实现了一个极其高效的寄存器解释器,所有指标都大幅优于其他热更新方案。[性能测试报告](https://hybridclr.doc.code-philosophy.com/docs/basic/performance) - 执行高效。实现了一个极其高效的寄存器解释器,所有指标都大幅优于其他热更新方案。[性能测试报告](https://www.hybridclr.cn/docs/basic/performance)
- 内存高效。 热更新脚本中定义的类跟普通c#类占用一样的内存空间,远优于其他热更新方案。[内存占用报告](https://hybridclr.doc.code-philosophy.com/docs/basic/memory) - 内存高效。 热更新脚本中定义的类跟普通c#类占用一样的内存空间,远优于其他热更新方案。[内存占用报告](https://www.hybridclr.cn/docs/basic/memory)
- 支持MonoPInvokeCallback可以与native代码或者其他语言如lua、javascript、python良好交互 - 支持MonoPInvokeCallback可以与native代码或者其他语言如lua、javascript、python良好交互
- 支持PInvoke - 支持PInvoke
- 支持一些il2cpp不支持的特性如\_\_makeref、 \_\_reftype、\_\_refvalue指令 - 支持一些il2cpp不支持的特性如\_\_makeref、 \_\_reftype、\_\_refvalue指令
@@ -67,7 +68,7 @@ HybridCLR已经被广泛验证是非常高效、稳定的Unity热更新解决方
目前已经有数千个商业游戏项目接入了HybridCLR其中有超过千个已经在App Store和Google Player上线仅仅iOS免费榜前500名中就有近百款使用了HybridCLR。上线的项目中包括MMORPG、重度卡牌、重度塔防之类的游戏。国内绝大多数**Top游戏公司**都已经在使用HybridCLR。 目前已经有数千个商业游戏项目接入了HybridCLR其中有超过千个已经在App Store和Google Player上线仅仅iOS免费榜前500名中就有近百款使用了HybridCLR。上线的项目中包括MMORPG、重度卡牌、重度塔防之类的游戏。国内绝大多数**Top游戏公司**都已经在使用HybridCLR。
可查看我们已知的头部公司中使用HybridCLR并且已经上线的[项目列表](https://hybridclr.doc.code-philosophy.com/docs/other/businesscase)。 可查看我们已知的头部公司中使用HybridCLR并且已经上线的[项目列表](https://www.hybridclr.cn/docs/other/businesscase)。
## 支持与联系 ## 支持与联系
@@ -77,7 +78,15 @@ HybridCLR已经被广泛验证是非常高效、稳定的Unity热更新解决方
- 新手3群2000人**920714552推荐** - 新手3群2000人**920714552推荐**
- discord频道 `https://discord.gg/BATfNfJnm2` - discord频道 `https://discord.gg/BATfNfJnm2`
- 商业合作邮箱: business#code-philosophy.com - 商业合作邮箱: business#code-philosophy.com
- [商业化支持](https://hybridclr.doc.code-philosophy.com/docs/business/intro) - [商业化支持](https://www.hybridclr.cn/docs/business/intro)
## 相关项目 LeanCLR
hybridclr仅是一个解释器模块如果你需要一个完整小巧的适合发布到移动和小游戏平台的开源CLR实现[LeanCLR](https://github.com/focus-creative-games/leanclr) 是当前最合适的方案。
LeanCLR 是一个面向全平台的精益 CLRCommon Language Runtime实现。LeanCLR 在高度符合 ECMA-335 规范的前提下提供更紧凑、易嵌入、低内存占用的运行时实现对移动端、H5 与小游戏等资源受限平台的友好支持。LeanCLR原生支持 AOT + Interpreter 混合执行模式,内置 IL 与 IR 双解释器。
LeanCLR既可以独立嵌入到任何app和游戏项目发布到任何平台也可以**替代il2cpp作为Unity团结引擎发布到webgl和小游戏平台的运行时**。大幅缩减包体和内存开销。
## 关于作者 ## 关于作者

View File

@@ -21,18 +21,19 @@ Welcome to embrace modern native C# hot update technology!
## Documentation ## Documentation
- [Official Documentation](https://hybridclr.doc.code-philosophy.com/en/docs/intro) - [Official Documentation](https://www.hybridclr.cn/en/docs/intro)
- [Quick Start](https://hybridclr.doc.code-philosophy.com/en/docs/beginner/quickstart) - [Quick Start](https://www.hybridclr.cn/en/docs/beginner/quickstart)
- [Business Project Cases](https://hybridclr.doc.code-philosophy.com/en/docs/other/businesscase) - [Business Project Cases](https://www.hybridclr.cn/en/docs/other/businesscase)
- [LeanCLR](https://github.com/focus-creative-games/leanclr)
## Features ## Features
- Nearly complete implementation of the [ECMA-335 specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-335/), with only a very small number of [unsupported features](https://hybridclr.doc.code-philosophy.com/en/docs/basic/notsupportedfeatures). - Nearly complete implementation of the [ECMA-335 specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-335/), with only a very small number of [unsupported features](https://www.hybridclr.cn/en/docs/basic/notsupportedfeatures).
- Zero learning and usage costs. For most developers, writing code is almost unrestricted. Hot update code works seamlessly with AOT code, allowing for inheritance, **generics**, **reflection**, and other code without additional special code or code generation. - Zero learning and usage costs. For most developers, writing code is almost unrestricted. Hot update code works seamlessly with AOT code, allowing for inheritance, **generics**, **reflection**, and other code without additional special code or code generation.
- Full support for multithreading, including but not limited to volatile, ThreadStatic, async Task, and related features and characteristics. This is not supported by any other hot update solution. - Full support for multithreading, including but not limited to volatile, ThreadStatic, async Task, and related features and characteristics. This is not supported by any other hot update solution.
- Almost complete compatibility with Unity's workflow. This includes support for hot updating **MonoBehaviour**, ScriptableObject, **DOTS** technology, and correctly instantiating hot update scripts mounted on resources, which is not supported by any other hot update solution. - Almost complete compatibility with Unity's workflow. This includes support for hot updating **MonoBehaviour**, ScriptableObject, **DOTS** technology, and correctly instantiating hot update scripts mounted on resources, which is not supported by any other hot update solution.
- Efficient execution. A highly efficient register interpreter has been implemented, with all indicators significantly better than other hot update solutions. [Performance Test Report](https://hybridclr.doc.code-philosophy.com/en/docs/basic/performance) - Efficient execution. A highly efficient register interpreter has been implemented, with all indicators significantly better than other hot update solutions. [Performance Test Report](https://www.hybridclr.cn/en/docs/basic/performance)
- Efficient memory usage. Classes defined in hot update scripts occupy the same memory space as ordinary C# classes, far superior to other hot update solutions. [Memory Usage Report](https://hybridclr.doc.code-philosophy.com/en/docs/basic/memory) - Efficient memory usage. Classes defined in hot update scripts occupy the same memory space as ordinary C# classes, far superior to other hot update solutions. [Memory Usage Report](https://www.hybridclr.cn/en/docs/basic/memory)
- Supports MonoPInvokeCallback, enabling good interaction with native code or other languages such as Lua, JavaScript, Python. - Supports MonoPInvokeCallback, enabling good interaction with native code or other languages such as Lua, JavaScript, Python.
- Supports some features not supported by il2cpp, such as __makeref, __reftype, __refvalue instructions. - Supports some features not supported by il2cpp, such as __makeref, __reftype, __refvalue instructions.
- Supports the unique **Differential Hybrid Execution (DHE)** technology, which allows for arbitrary additions, deletions, and modifications to AOT DLLs. It intelligently runs unchanged functions in AOT mode and changed or newly added functions in interpreter mode, bringing the performance of hot-updated game logic close to that of native AOT. - Supports the unique **Differential Hybrid Execution (DHE)** technology, which allows for arbitrary additions, deletions, and modifications to AOT DLLs. It intelligently runs unchanged functions in AOT mode and changed or newly added functions in interpreter mode, bringing the performance of hot-updated game logic close to that of native AOT.
@@ -65,7 +66,7 @@ HybridCLR has been widely verified as an efficient and stable Unity hot update s
Currently, thousands of commercial game projects have integrated HybridCLR, with over a thousand already launched on the App Store and Google Play. Nearly a hundred of the top 500 free iOS games use HybridCLR, including MMORPGs, heavy card games, and heavy tower defense games. Most of the **Top Game Companies** in China are already using HybridCLR. Currently, thousands of commercial game projects have integrated HybridCLR, with over a thousand already launched on the App Store and Google Play. Nearly a hundred of the top 500 free iOS games use HybridCLR, including MMORPGs, heavy card games, and heavy tower defense games. Most of the **Top Game Companies** in China are already using HybridCLR.
You can view the [list of known top companies using HybridCLR and their launched projects](https://hybridclr.doc.code-philosophy.com/en/docs/other/businesscase). You can view the [list of known top companies using HybridCLR and their launched projects](https://www.hybridclr.cn/en/docs/other/businesscase).
## Support and Contact ## Support and Contact
@@ -75,7 +76,13 @@ You can view the [list of known top companies using HybridCLR and their launched
- Beginner Group 3: **920714552 (Recommended)** - Beginner Group 3: **920714552 (Recommended)**
- Discord channel https://discord.gg/BATfNfJnm2 - Discord channel https://discord.gg/BATfNfJnm2
- Business cooperation email: business#code-philosophy.com - Business cooperation email: business#code-philosophy.com
- [Commercial Support](https://hybridclr.doc.code-philosophy.com/en/docs/business/intro) - [Commercial Support](https://www.hybridclr.cn/en/docs/business/intro)
## LeanCLR Project
HybridCLR is just an interpreter module. If you need a complete, compact, open-source CLR implementation suitable for mobile and mini-game platforms, [LeanCLR](https://github.com/focus-creative-games/leanclr) is currently the best solution.
LeanCLR can be embedded independently into any app or game project and published to any platform. It can also **replace il2cpp as the runtime for Unity (Unity Engine) when publishing to webgl and mini-game platforms**, greatly reducing package size and memory usage.
## About the Author ## About the Author

View File

@@ -1,5 +1,146 @@
# ReleaseLog # ReleaseLog
## 8.11.0
Release Date: 2026-02-28.
### Runtime
- [fix] fix methodPointer of Full Generic Sharing Method may not be initialized in some cases, which leads to methodPointerCallByInterp not initialized correctly.
- [fix] handle intrinsic System.Array.UnsafeMov specially. It will raise unbox exception if runs this generic method at interpreter mod.
- [fix] adjust data type at stack top after JitHelper::UnsafeCast and JitHelper::UnsafeEnumCastLong.
- [fix] **6000.3.x**: fix bug of comparing MVAR in IsSameOverrideType
## 8.10.0
Release Date: 2026-02-24.
### Runtime
- fix: fix bug of computing interface vtable implement when re-implements interface in child class.
- fix: for arrays whose element type is a value type, `ldelema` no longer performs type-matching checks.
Although this does not strictly follow the ECMA-335 specification, it is consistent with the behavior of Mono and CoreCLR.
- fix: fix bug that didn't handle RuntimeOptionId::MaxInlineableMethodBodySize in RuntimeConfig::GetRuntimeOption and RuntimeConfig::SetRuntimeOption.
- fix: assign FindImageByAssembly result to image in PreJitClass
- fix: use strict bounds in CheckMulOverflow for int32 and uint32
- fix: fix arguments overflow when method argument count > 256 in InvokeDelegateBeginInvoke.
### Editor
- [new]: support BuildTarget GameCoreXboxOne and GameCoreXboxSeries.
## 8.9.0
Release Date: 2026-01-12.
### Runtime
- [fix] **Unity 6.3.x**: fix bug that didn't handle interpreter type in GlobalMetadata::GetNestedTypes
- [fix] **Unity 6.3.x**: fix crash on GlobalMetadata::GetMethodHandleFromMethodInfo because it maybe passed null as methodInfo in setup vtable.
- [fix] **TUANJIE**: fix IL2CPP_ASSERT fail in Class::GetVirtualMethod when klass is generic class and not initialized, at this time klass->vtable_count == 0
- [fix] **TUANJIE**: fix the bug that didn't initialize method->klass->rgctx_data after GenericMetadata::InflateRGCTXMethod
- [change] **TUANJIE**: [merge] merge il2cpp changes from tuanjie 1.6.7 to 1.6.8
## 8.8.0
Release Date: 2025-12-14.
### Runtime
- [new] support 6000.3.x
- [new] add instructions for ldfld and stfld while field offset >= 2^16
- [fix] fix offset overflow issue for ldflda, ldfld, stfld while offset >= 2^16
- [fix] fix bug of comparing array rank
### Editor
- [new] support 6000.3.x
- [fix] fix deprecated warning of `PlayerSettings.GetScriptingBackend(BuildTargetGroup)` in Unity 6000
## 8.7.0
Release Date: 2025-11-03.
### Runtime
- [fix] fix a crash issue in IH_object_ctor caused by `ctx.GetCurbb()->insts` may be empty in obfuscated code
- [merge] **Unity 6000***: merge il2cpp changes from 6000.0.44 to 6000.0.60
- [merge] **TuanJie**: merge il2cpp changes from tuanjie 1.6.5 to 1.6.7
### Editor
- [fix] fix raising NullReferenceException in generating MethodBridge for MonoPInvokeCallbackAttribute while constructor arguments is empty.
## 8.6.0
Release Date: 2025-09-27.
### Runtime
- [fix] fix the crash in InterpreterDelegateInvoke when compiled in Release mode on Xcode 26.x. This bug is caused by an optimization issue in the newer Clang version.
- [fix] [tuanjie] fix a bug on tuanjie that calling Init of Il2CppClass `Nullable<EnumType`> may not init Il2CppClass of EnumType, which causes crash when box `Nullable<EnumType>`
- [fix] [tuanjie] fix bug that computation of method index in Class::GetGenericInstanceMethodFromDefintion. tuanjie 1.6.4 only fixes it when IL2CPP_ENABLE_LAZY_INIT.
- [merge] merge il2cpp of tuanjie changes from 1.6.0-1.6.4
### Editor
- [fix] fix the bug that BashUtil.CopyDir calls UnityEditor.FileUtil.CopyFileOrDirectory failed when parent directory of dst does not exist.
## 8.5.1
Release Date: 2025-08-25.
### Runtime
- [fix] **CRITICAL!!!** fixed stack calculation bug in instinct transform for `System.Activator.CreateInstance<T>()` when T is value type.
### Editor
- [fix] fixed PInvokeAnalyzer bug in computing PInvoke function calling conventions.
## 8.5.0
Release Date: 2025-08-20.
### Runtime
- [new] AOTHomologousImage supports custom image format
- [fix] Throw an exception when the number of function parameters exceeds 255, as the parameter count type in il2cpp is uint8_t.
- [fix] fix incorrect type conversions for MethodInfo.parameter_count and Il2CppMethodDefinition.parameterCount.
### Editor
- [change] BashUtil::CopyDir replaces CopyWithCheckLongFile with CopyUnityEditor.FileUtil.CopyFileOrDirectory
## 8.4.0
Release Date: 2025-07-26.
### Runtime
- **[new] IMPORTANT! support custom image format**
- [change] the type of field `offset` of ldsfld, stfld, ldthreadlocalfld、stthreadlocalfld changed from uint16_t to uint32_t so that supports class with huge static fields.
- [opt] optimize to use NewValueTypeVar_Ctor_0 for new zero-argument value type and System.Activator.CreateInstance&lt;T&gt;()
- [opt] optimize new ValueType with zero arguments.
### Editor
- [fix] fix the issue that `Texture Compression` option in Build Settings was changed after running `HybridCLR/Generate/All` on Android platform
## 8.3.0
Release Date: 2025-07-04.
### Runtime
- [fix] fix the bug where RuntimeInitClassCCtor was executed during InterpreterModule::GetInterpMethodInfo. This caused the type static constructor to be incorrectly executed prematurely during PrejitMethod.
- [fix] fix bug that JitMethod jit method of generic class incorrectly.
- [merge] merge il2cpp of tuanjie changes from 1.5.0-1.6.0
### Editor
- [fix] fix the bug that not collect struct in calli and extern method signature in generating MethodBridge.
## 8.2.0 ## 8.2.0
Release Date: 2025-06-12. Release Date: 2025-06-12.

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 006be2ba6588a8b4989d3724bb01d8b7 guid: 13ba8ce62aa80c74598530029cb2d649
AssemblyDefinitionImporter: AssemblyDefinitionImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@@ -11,6 +11,9 @@ namespace HybridCLR
HOMOLOGOUS_ASSEMBLY_HAS_LOADED, // can not load supplementary metadata assembly for the same assembly HOMOLOGOUS_ASSEMBLY_HAS_LOADED, // can not load supplementary metadata assembly for the same assembly
INVALID_HOMOLOGOUS_MODE, // invalid homologous image mode INVALID_HOMOLOGOUS_MODE, // invalid homologous image mode
PDB_BAD_FILE, // invalid pdb file PDB_BAD_FILE, // invalid pdb file
UNKNOWN_IMAGE_FORMAT,
UNSUPPORT_FORMAT_VERSION,
UNMATCH_FORMAT_VARIANT,
}; };
} }

View File

@@ -1,11 +1,11 @@
{ {
"name": "com.code-philosophy.hybridclr", "name": "com.code-philosophy.hybridclr",
"version": "8.2.0", "version": "8.11.0",
"displayName": "HybridCLR", "displayName": "HybridCLR",
"description": "HybridCLR is a fully featured, zero-cost, high-performance, low-memory solution for Unity's all-platform native c# hotupdate.", "description": "HybridCLR is a fully featured, zero-cost, high-performance, low-memory solution for Unity's all-platform native c# hotupdate.",
"category": "Scripting", "category": "Scripting",
"documentationUrl": "https://hybridclr.doc.code-philosophy.com/#/", "documentationUrl": "https://www.hybridclr.cn/#/",
"changelogUrl": "https://hybridclr.doc.code-philosophy.com/#/other/changelog", "changelogUrl": "https://www.hybridclr.cn/#/other/changelog",
"licensesUrl": "https://github.com/focus-creative-games/hybridclr_unity/blob/main/LICENSE", "licensesUrl": "https://github.com/focus-creative-games/hybridclr_unity/blob/main/LICENSE",
"keywords": [ "keywords": [
"HybridCLR", "HybridCLR",