Question

I have successfully created an updated ZBar MonoTouch binding dll, following up on this answer here from a while ago, using the updated [Field] bindings to bind static NSStrings (previously I was just duplicating the value of the NSString in my binding dll).

The binding dll compiles fine (Compiled in Release mode).

And using the binding ZBar.dll from my app works fine in Debug builds, returning the correct NSString value from the native lib. However in Release builds it always returns null.

Note that I have the linker behaviour set to strip all assemblies for both Debug and Release builds, so it's nothing to do with the linker stripping anything out.

I tried turning off the LLVM compiler for Release, and it still returns null in Release builds. However enabling debugging in Release builds fixes it (obviously not a solution though).

Heres the binding code:

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

And here's the decompiled IL (According to 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;
            }
        }
    }
}

Monotouch: 6.0.10

Was it helpful?

Solution

Add this to the additional mtouch arguments in the project's iOS Build options page:

--nosymbolstrip=ZBarReaderControllerResults

The difference between Debug and Release builds is that Release builds are stripped, thus removing the symbol for the field, so Xamarin.iOS can't find it at runtime. This option will make Xamarin.iOS tell the linker that it should keep that symbol, even if the symbol is not used (note that the binding to the field is a dynamic binding which happens at runtime, so the native strip tool is not able to see that the field is actually used).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top