locked
Binding a native library to Xamarin.Mac project RRS feed

  • Question

  • User381382 posted

    Hello,

    Before unifying mono APIs, I was linking a native library (Sparkle) by creating it using bmac and a .cs linking the methods of the lib in c# and then using Dlfcn.dlopen() to load the assembly.

    Worked great, but now when I want to compile the library using the latest mono version (and the latest Sparkle version), it tells me: Could not find the type MonoMac.Foundation.NSObject in the assembly Xamarin.Mac

    I have found some posts where this method was used to linked some native libraries, I just can't figure out why it does not compile anymore. Here is a sample of the code in the .cs:

    using System;
    using Foundation;
    using ObjCRuntime;
    using AppKit;
    
        namespace AppMac.ObjC.Frameworks
        {
            [BaseType (typeof (NSObject))]
            public partial interface LoginItem {
    
                [Static, Export ("willStartAtLogin:")]
                bool WillStartAtLogin (string itemURL);
    
                [Static, Export ("setStartAtLogin:enabled:")]
                void SetStartAtLogin (string itemURL, bool enabled);
            }
    
            [BaseType (typeof (NSObject))]
            public partial interface SharedItem {
    
                [Static, Export ("addPathToSharedItem:")]
                void AddPathToSharedItem (string path);
            }
        }
    

    When I compile with some other Xamarin.Mac.dll, I get errors like 'BaseType not found'.

    Here is how I create it: $(XAMMAC)/bin/bmac sparkle.cs --tmpdir=xamarin -baselib=$(XAMMAC_DLL) -sourceonly xamarin/sources.list mcs -target:library -unsafe -out:$@ @xamarin/sources.list -r:System.Drawing -r:$(XAMMAC_DLL)

    Where XAMMAC is the path of the xamarin.mac.framework folder and XAMMAC_DLL its dll.

    Am I doing something wrong? Is it not possible to do this anymore with the new unified APIs?

    Tuesday, February 12, 2019 2:39 PM

All replies

  • User35201 posted

    I would strongly suggest moving to a binding project instead of invoking the tooling by hand. There are multiple issues with your invocation, and the project msbuild will call things correctly for you.

    If you have a reasonable reason for not using binding projects, I can dig out the correct invocation.

    Tuesday, February 12, 2019 3:35 PM
  • User381382 posted

    I totally agree. I would love to create a binding project. As explained in the other post I created (I will close it and continue here I guess, sorry about that), I can't succeed to link a binding project to my main project. I said it compiled and then crashed at launch, but I guess it does not even compile anymore.

    Here is how I do:

    • Creating the binding project, linking the outside framework (Sparkle) into the native references
    • Putting all binding methods into the ApiDefinition.cs
    • Changing to a Xamarin.Mac unsupported 4.5.2 (by adding <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> into the .csproj) so it can be referenced by my main project (which is also on unsupported 4.5.2) ; if I stay on full or modern, it says the project has an incompatible target framework when trying to reference it into my main project
    • Reference the project into my main project
    • Compiling main project

    And I have the following compilation error:

    xcrun -sdk macosx clang -mmacosx-version-min=10.7 -arch x86_64 -fobjc-runtime=macosx -Wno-unguarded-availability-new -ObjC -lsqlite3 -F [loads of stuff]
    /Users/.../obj/Debug/mmp-cache/registrar.m(38214,17): warning GC27A339F: method 'deviceBrowserView:selectionDidChange:' in protocol 'IKDeviceBrowserViewDelegate' not implemented [-Wprotocol]
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/Quartz.framework/Frameworks/ImageKit.framework/Headers/IKDeviceBrowserView.h:31:1: note: method 'deviceBrowserView:selectionDidChange:' declared here
    Undefined symbols for architecture x86_64:
      "_OBJC_CLASS_$_LoginItem", referenced from:
          objc-class-ref in registrar-5e2f13.o
      "_OBJC_CLASS_$_SharedItem", referenced from:
          objc-class-ref in registrar-5e2f13.o
    ld: symbol(s) not found for architecture x86_64
    clang : error : linker command failed with exit code 1 (use -v to see invocation)
    

    I feel like I am tinkering my way to a solution and it makes me go deeper into tinkering afterward. Do you have an idea on why I get this error here and how it can be fixed? Or am I doing something wrong in the first place?

    Tuesday, February 12, 2019 3:54 PM
  • User35201 posted

    Can you run file on your shared library and verify it has an x86_64 version?

    _OBJC_CLASS_$_SharedItem looks more like a i386 symbol?

    Can you try swapping your XM app to 32-bit and see if makes a difference?

    Tuesday, February 12, 2019 3:58 PM
  • User381382 posted

    On the Sparkle.dll created by the binding project I had this:

    Sparkle.dll: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows

    Then I compiled the binding project into 64 bit and got this:

    Sparkle.dll: PE32+ executable (DLL) (console) x86-64 Mono/.Net assembly, for MS Windows

    I have the same compilation problem on both.

    Also, the Sparkle framework has this file in their framework folder:

    Sparkle: Mach-O 64-bit dynamically linked shared library x86_64

    This is what I tried to link using the method I wrote earlier (Dlfcn.dlopen()).

    EDIT: I tried compiling into 32 bit but it tells me my Xcode version only allows 64 bit compilation.

    Tuesday, February 12, 2019 4:15 PM
  • User35201 posted

    Could you simplify your test project and attach it here? No one is able to help with just error messages pasted.

    Tuesday, February 12, 2019 5:39 PM
  • User381382 posted

    I may have found the problem. When creating the test project I realised it worked until I added the .cs bindings. It seems the bindings I used (the ones from a community integration of Sparkle that is 2 years old) where not all correct.

    So I guess I will go through the Sparkle headers one by one and create the integration myself :smile:

    I will keep you in touch if I succeed and maybe create a new github for the people needing it like me.

    Thanks a lot for your help and patience Chris :smiley:

    Wednesday, February 13, 2019 9:56 AM