我正在尝试在“仅链接SDK”模式下使用MonoTouch编译我的iOS应用程序。如果我完全关闭链接,它可以完全正常地编译,但是它还会生成一个不适合发布模式的巨大二进制文件。
不幸的是,我需要的一种库以某种方式调用Expression.Visit,我无法弄清楚如何指示链接器不要将其剥离。这导致此编译错误:
错误MT2002:无法解决“ System.Core,版本= 2.0.5.0,区域性=中性”引用中的“ System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor :: Visit(System.Linq.Expressions.Expression)”引用,PublicKeyToken = 7cec85d7bea7798e“(MT2002)(MyApp)
根据有关自定义链接的文档,我已经设置了一个链接器文件以尝试阻止这种情况的发生:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor">
<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
</type>
</assembly>
</linker>
不幸的是,这没有任何作用-错误只是像以前一样发生。
文档中提到了preserve="fields"
我可以提供给的参数<type>
,因此我尝试了以下操作:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor" preserve="methods" />
</assembly>
</linker>
那也不起作用。
然后,我在文件中引入了XML语法错误,并且构建失败,因为它无法解析链接器文件,因此我至少知道该文件正在读取。
但是后来我尝试在程序集名称中引入错误:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="NonexistentAssembly">
</assembly>
</linker>
导致错误,抱怨装配无法解决。
然后,我尝试修改类型名称:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="NonExistentType" preserve="methods" />
</assembly>
</linker>
现在,它刚刚开始显示我之前看到的相同的“无法解析expressionvisitor :: visit”错误。似乎没有检查类型名称。
另外,签名名称都不是,因为这也呈现相同的编译错误。
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor">
<method signature="jg98j23890rj2390erk90fk3ew!]['##'#'[" />
</type>
</assembly>
</linker>
因此,似乎只要您指定程序集名称并具有有效的XML结构,链接器文件就不会引发任何异常。但是,链接器文件的文档对于这样一个复杂的主题不是特别冗长,并且包含许多语法错误,即:
<type fullname="Foo" preserve="fields" />
<method name=".ctor" />
</type>
此外,它没有提供链接器文件格式的技术描述,因此我的定义完全有可能完全错误。
我也尝试过完全跳过System.Core的链接,--linkskip=System.Core
但这没有任何效果。无论是否使用,我都尝试过此标志--xml
。
在MvvmCross项目中,我尝试指定一个新类来调用Visit方法,其样式与MvvmCross NuGet包添加到每个iOS项目的LinkerPleaseInclude.cs文件的样式相同:
[Preserve]
public class PleaseIncludeVisitor : ExpressionVisitor
{
public PleaseIncludeVisitor()
{
this.Visit(null);
}
}
不幸的是,这也没有效果。
我目前正在使用Mono 3.2.6((no / 9b58377)和Xamarin.iOS v7.0.7.2。
主要问题是无法在iOS上的运行时进行代码生成。
这意味着,有很大一部分System.Linq.Expressions
会,通常情况下,是不可能在正常情况下提供(就像System.Refection.Emit
不能提供)。
要解决此Xamarin.iOS,它已提供了一种替代实现(可以解释最常见的表达式)。
但是,当前代码不是与.NET框架100%兼容的API(已修复,但尚未发布)。例如
System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)
以上内容void
在当前的Xamarin.iOS(7.0.x)版本中返回。这就是链接器抱怨(这不是错误)的原因,因为它找不到该成员引用(如果找不到,则无法重新创建较小的链接的程序集)。无法保留不存在的成员(这就是为什么您尝试使用XML文件或属性将无济于事的原因)。
在目前的解决办法是,以确认哪些组件使用这个API并重建(源文件)使用现有的System.Core.dll
随机附带Xamarin.iOS。
笔记
我不知道如何指示链接器不要将其剥离。
链接器不会尝试将其删除,而是尝试将其保留(即,它必须加载引用才能将其保存回去)。但是,System.Core.dll
由于无法提供程序集的有效链接版本,因此无法找到该成员。
<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
这就要求保留一些不存在的东西。它将被忽略,即,void
找到-returning版本时,它将与XML描述不匹配。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句