【问题标题】:MonoTouch Binding to NSString Field returning null in Release buildsMonoTouch 绑定到 NSString 字段在 Release 版本中返回 null
【发布时间】:2013-03-05 05:27:52
【问题描述】:

我已成功创建更新的 ZBar MonoTouch 绑定 dll,following up on this answer here from a while ago,使用更新的 [Field] 绑定来绑定静态 NSString(以前我只是在绑定 dll 中复制 NSString 的值)。

绑定 dll 编译良好(在发布模式下编译)。

并且使用我的应用程序中的绑定 ZBar.dll 在调试版本中工作正常,从本机库返回正确的 NSString 值。但是在 Release 版本中,它总是返回 null。

请注意,我已将链接器行为设置为剥离调试和发布版本的所有程序集,因此与链接器剥离任何内容无关。

我尝试为 Release 关闭 LLVM 编译器,但它在 Release 构建中仍然返回 null。然而,在 Release 版本中启用调试可以修复它(但显然不是解决方案)。

以下是绑定代码:

[Static]
interface ZBarSDK
{
    // extern NSString* const ZBarReaderControllerResults;
    [Field ("ZBarReaderControllerResults", "__Internal")]
    NSString BarcodeResultsKey { get; }
}

这是反编译的 IL(根据 MonoDevelop):

namespace ZBar
{
    public static class ZBarSDK
    {
        [CompilerGenerated]
        private static NSString _BarcodeResultsKey;

        [CompilerGenerated]
        private static readonly IntPtr __Internal_libraryHandle = Dlfcn.dlopen(null, 0);

        public static NSString BarcodeResultsKey
        {
            get
            {
                if (ZBarSDK._BarcodeResultsKey == null)
                {
                    ZBarSDK._BarcodeResultsKey = Dlfcn.GetStringConstant(ZBarSDK.__Internal_libraryHandle, "ZBarReaderControllerResults");
                }
                return ZBarSDK._BarcodeResultsKey;
            }
        }
    }
}

单点触控:6.0.10

【问题讨论】:

  • 您确定需要 FieldAttribute 的“__Internal”第二个参数吗?
  • @StephaneDelcroix 是的,根据binding docs here (Field section)如果是静态链接,没有库可以绑定,所以需要使用__内部名称跨度>
  • @StephaneDelcroix 此外,启用调试模式时它确实有效。你会认为这样的事情会在所有情况下都破坏它。

标签: c# objective-c zbar-sdk xamarin.ios


【解决方案1】:

将此添加到项目的 iOS 构建选项页面中的其他 mtouch 参数中:

--nosymbolstrip=ZBarReaderControllerResults

Debug 和 Release 版本之间的区别在于 Release 版本被剥离,因此删除了该字段的符号,因此 Xamarin.iOS 在运行时找不到它。此选项将使 Xamarin.iOS 告诉链接器它应该保留该符号,即使未使用该符号(请注意,与字段的绑定是在运行时发生的动态绑定,因此本机 strip 工具不是能够看到该字段实际被使用)。

【讨论】:

  • 谢谢,这听起来很有希望,明天将进行测试。出于好奇,我们在谈论哪一层链接?这不是托管的 IL 链接/剥离吗?您是说从预编译的本机 Zbar lib 文件中剥离了本机符号吗?我不知道这发生在MT内部?这在任何地方都有记录吗?
  • 这是原生剥离工具(从终端运行 man strip 以查看更多信息)。这是默认情况下由 Xamarin.iOS 完成的,用于发布版本以使其更小。如果您想了解其中的区别,可以将 --nosymbolstrip(不带任何参数)传递给 mtouch 以完全禁用此功能。
  • 好的,谢谢 Rolf!但是我需要删除下划线前缀,即我使用了--nosymbolstrip=ZBarReaderControllerResults。这只是您的回答中的一个错字吗?
  • 然而,这个修复并不是一个理想的解决方案——这意味着每个使用 ZBar.dll 的应用程序都需要执行这个配置。有没有办法将此指令嵌入 MT,我的意思是 Xamarin.iOS ;) 绑定 ZBar.dll 本身?
  • @Tyson:我不确定是否是下划线,我想我猜错了(我现在已经修复了答案)。这个想法是最终让 Xamarin.iOS 自动检测这些字段,并且根本不需要传递 --nosymbolstrip。
猜你喜欢
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
相关资源
最近更新 更多