iOS 上的 C# IL2CPP 通过反射调用泛型方法

2024-01-07

这个问题专门针对 Unity3d IL2CPP 和 iOS。

使用反射调用泛型方法

class SourceValue<T> { public T value; }
class TargetValue<T> { public T value; }

static TargetValue<T> GenericMethod<T> (SourceValue<T> source) {
    return new TargetValue<T> { value = source.value };
}

void Main () {
    Type genericType = typeof(SourceValue<float>);
    Type typeArg = genericType.GenericTypeArguments[0];
    MethodInfo mi = GetType ().GetMethod ("GenericMethod", Flags | BindingFlags.Static);
    MethodInfo gmi = mi.MakeGenericMethod (typeArg);
    object src = new SourceValue<float> { value = 0.5f };
    object trg = gmi.Invoke (this, new object[] { src });
}

在 Mac 上的 Unity 编辑器中运行时,它可以按预期工作。在 iOS 上调用失败并出现错误:

ExecutionEngineException: Attempting to call method 'GenericMethod<System.Single>' for which no ahead of time (AOT) code was generated.
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0  

仅仅是 AOT 系统无法调用泛型方法还是我遗漏了一些东西?


是的,由于 IL2CPP 是一个提前 (AOT) 编译器,因此它仅适用于编译时存在的代码。这里没有代码使用GenericMethod<float>在“真正的”C# 源代码中,因此 IL2CPP 不知道生成相应的代码以使该实现工作。

这里真正的限制是泛型参数类型是float,这是一个值类型。你可以使用string(引用类型)在这种情况下没有任何问题。 IL2CPP 共享具有引用类型泛型参数的所有泛型类型的实现(例如string, object, ETC。)。这是可能的,因为 C# 中的所有引用类型都具有相同的大小 (IntrPtr.Size,准确地说)。

所以这里的限制实际上有两个:

  1. IL2CPP只能生成编译时知道的代码
  2. 当类型参数是值类型时,此限制仅适用于泛型类型。

请注意,理论上 IL2CPP 也可以与值类型泛型参数共享泛型类型的实现,尽管尚未实现。

编辑:从 Unity 2022.2 开始,这已经实现 -ExecutionEngineException不会再发生了,原来的场景会起作用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 上的 C# IL2CPP 通过反射调用泛型方法 的相关文章

随机推荐

  • 带有 LLVM 的 C ABI

    我有一个用 LLVM 编写的编译器 我希望提高 ABI 合规性 例如 我发现很难在 Windows x86 或 Linux 上实际找到 C ABI 的规范文档 我发现的那些用 RAX EAX 等术语解释它 而不是我可以使用的 IR 术语 到
  • 如何:动态移动 Google Gauge?

    观察 CPU 和内存指标 http code google com apis visualization documentation gallery gauge html Loading一会儿 它们动态地移动 下面显示的示例代码不会像那样移
  • 来自 nginx/passenger 的“从应用程序收到的响应不完整”

    我尝试通过 capistrano 在 nginx 和 ubuntu 上部署我的 Rails 应用程序 就像页面上的教程一样https gorails com deploy ubuntu 14 04 https gorails com dep
  • Java 8 替代 Map.entry() 将值映射到新 Map?

    我找到了解决长期以来一直试图解决的问题的解决方案 不幸的是 我无法使用该解决方案 因为目标 java 版本是 Java 8 Map
  • 如何在大型 SQL Server 查询中使用多个核心?

    我有两台 SQL Server 一台用于生产 一台用作存档 每天晚上 我们都会运行一个 SQL 作业并将当天的生产数据复制到存档中 随着我们的成长 这个过程需要的时间越来越长 当我观察运行归档进程的归档服务器上的利用率时 我发现它只使用单个
  • C# 中的 Jaro–Winkler 距离算法

    如何在 C 中实现 Jaro Winkler 距离字符串比较算法 public static class JaroWinklerDistance The Winkler modification will not be applied un
  • 使用 log4j 编写审核日志

    我有一个应用程序需要写入两种不同类型的日志 应用程序日志和审核日志 应用程序日志用于调试目的 而审核日志用于记录所执行的操作 两个日志将位于不同的文件中 每个文件应仅包含上述日志 意味着审核日志文件不能包含应用程序日志 反之亦然 如何使用
  • 在 Node.js 中缓存数据最便宜的方法?

    我正在实现一个运行匹配算法的 Node js 服务器 由于我希望服务器尽快响应 因此我希望能够从缓存中检索数据 而不是每次都查询数据库 例如 我需要保留 10000 50000 个用户的信息 我担心这会占用大量内存 有没有什么方法可以将这么
  • Nodemailor 无法跨域发送电子邮件

    我正在使用 NodeMailor 通过 Node 和 Express 应用程序发送电子邮件 问题 当我跨域发送电子邮件时 例如 我正在使用 Hostgator 电子邮件服务器 它仅使用 Hostgator 在托管电子邮件上发送电子邮件 但当
  • 如何使用 htaccess 强制使用 http- 而不是 https

    我的整个域有一个目录 我想强制使用 https 即 docs 在 docs 文件夹中 我有以下 htaccess 文件 RewriteEngine On RewriteCond HTTPS on RewriteRule https HTTP
  • 在 ngIf 内动态添加组件

    我有一些代码可以动态地向我的页面之一添加 删除组件 这似乎工作得很好 我的方法基于 Rob Wormald 的很棒的方法NG2 高级讲座 https www youtube com watch v ZqGvilzDbac 以标准方式做事看起
  • html文本框的最大长度是多少

    任何人都可以帮助我确定普通 HTML 文本框中可以包含的最大字符长度 至于 HTML 方面 当maxlength未指定属性 则输入值的最大长度不受限制 但是 如果您将请求发送为GET代替POST 那么限制将取决于 Web 浏览器和 Web
  • 如何使用 Boost.Asio 解析主机(仅)?

    根据文档 http www boost org doc libs 1 36 0 doc html boost asio reference ip basic resolver query basic resolver query html
  • 如何在 C# 中使用堆栈计算 Infix-Expression 的输出

    我已经在 Stackoverflow 上找到了不同的解决方案 但有些事情我不明白 计算输出的最佳方法是什么 例如 1 4 2 3 2 3 4 5 我的方法如下 但我知道其中有很多错误 public static int ComputeInf
  • 将多条记录导入 CRM

    如何将数千条记录导入 CRM 我有一个可能包含数千条记录的列表 并希望在 CRM 中创建这些记录 目前 我有一个接收列表的方法 该方法调用另一个方法来批量创建 200 条记录 直到创建整个列表 最初一次是 1000 个 因为这是 Execu
  • 如何从一个字节中获取某个位置的某个位的值?

    如果我有一个字节 该方法将如何检索某个位置的位 这是我所知道的 但我认为这不起作用 public byte getBit int position return byte ID gt gt position 1 where ID是我从中检索
  • 如何在多个设备上同时运行 Monkeyrunner 脚本

    我正在尝试在多个设备上运行 Monkeyrunner 脚本来执行一些基本操作 我发现最初我将开始编写一个脚本来在两个连接的设备中执行基本操作 from com android monkeyrunner import MonkeyRunner
  • 如何在Python中将所有打印导出到.txt文件? [复制]

    这个问题在这里已经有答案了 可能的重复 将 stdout 重定向到 Python 中的文件 https stackoverflow com questions 4675728 redirect stdout to a file in pyt
  • PHP:从对象获取单个键

    我有一个带有单个键及其值的对象 但我不知道访问它的密钥 在不枚举对象的情况下获取密钥的最有效方法是什么 如果你只是想访问值 你不需要钥匙 实际上属性名称 完全 value current array object 如果你真的想要属性名称 尝
  • iOS 上的 C# IL2CPP 通过反射调用泛型方法

    这个问题专门针对 Unity3d IL2CPP 和 iOS 使用反射调用泛型方法 class SourceValue