Binding a native library to Xamarin.Mac project

MatthieuDMatthieuD Member ✭✭
edited February 12 in Xamarin.Mac

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:[email protected] @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?

Posts

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    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.

  • MatthieuDMatthieuD Member ✭✭
    edited February 12

    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?

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    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?

  • MatthieuDMatthieuD Member ✭✭
    edited February 12

    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.

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

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

  • MatthieuDMatthieuD Member ✭✭
    edited February 13

    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:

Sign In or Register to comment.