Xamarin.Mac Binding Project Preview

ChrisHamonsChrisHamons Chris HamonsUSXamarin Team Xamurai

Improving Xamarin.Mac support for binding Objective-C libraries has been an often requested feature. I'm excited to announce that in our next major release will have major improvements in this area.

We're releasing a preview of this support today.

These previews are very early, unsupported builds to allow developers to test the new features to gather feedback and bug reports. Your help is very appreciated!

Features:

  • Binding project templates, which simplify the process of generating managed binding assemblies. These will be familiar to many users of Xamarin.iOS.
  • Support for the LinkWith attribute, which allows binding assemblies to embed the native library being bound inside themself. This can greatly simplify the build process of application that consume native libraries.

Links:

Please note, you will need to install both Xamarin.Mac and Xamarin Studio for the binding project templates to be available.

Documentation:
As this is a preview, we do not have full documentation support, but this iOS documentation for binding objective-c libraries may be useful.

https://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/binding_objc_libs/

Known issues:

  • There are reports of issues binding frameworks (not .a or .dylib files) with binding projects. If you run into issues, please post here, and we may be able to get you a work around until we fix it.

Please report issues to Xamarin via bugzilla.xamarin.com or posting here. You can also ask questions below as well.

Tagged:

Posts

  • PaulBeddisPaulBeddis Paul Beddis GBMember

    Really excited about this functionality...

    However I downloaded the preview and can't make a Mac Bindings library work for a target framework of Xamarin.Mac .NET 4.5 framework.

    Steps to reproduce:

    Open a new project
    In the new project go to Build>General
    Change Target Framework from the default of Xamarin.Mac Mobile Framework to Xamarin.Mac .NET 4.5 Framework
    Press OK <-- at this point the OK button does nothing for me, the dialog will not close.

    So a couple of questions:
    1) Am I doing anything wrong?
    2) Why is there even a Target Framework of Xamarin.Mac Mobile? As a name, in the context of Xamarin.Mac, it doesn't make sense to me.

    What I am trying to achieve is to use a Xamarin.Mac Binding Library in a Xamarin.Mac application. The Xamarin.Mac app has a target framework of .NET 4.5, which is why I'm trying to build the Binding library as .NET 4.5. I have already established that the .NET 4.5 application will not allow me to reference a bindings library built with a target framework of Xamarin.Mobile.

    Help please!

    I am really keen to see all of this working properly, it will be crucial to our development plans

    Paul

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    So you seem a bit confused on the target framework options. You can read about them here: http://developer.xamarin.com/guides/mac/advanced_topics/target-framework/

    But it looks like a nasty bug slipped by us. I also can not hit OK in that dialog when picking the XM 4.5 option. I've filed a bug here:

    https://bugzilla.xamarin.com/show_bug.cgi?id=38253

    I'm working on fixing that now. If you are comfortable with a text editor, you can open up your csproj and add these lines:

    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
    

    to the first PropertyGroup like:

    https://gist.github.com/chamons/51720b2c6b7470170506

  • PaulBeddisPaulBeddis Paul Beddis GBMember

    Ok I'll re-read the target framework documentation in a bit.

    In the meantime I've manually edited the csproj file as suggested, now I get this error when the project tries to load:

    Load failed: Project does not support framework '.NETFramework, Version=v4.5'

    Do you get the same?

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    You are correct. My automated tests build from the command line (xbuild foo.csproj work) but this bug is related to the XS GUI.

    Now obviously you could edit the csproj as described, then edit the text files in a text editor and build from the command line, but this is rather unacceptable.

    Let me see how difficult it would be to get a fix released. Apologies for the trouble (but thanks for catching this pain early!)

  • PaulBeddisPaulBeddis Paul Beddis GBMember

    Cool, let me know when a fix is available and I'll resume my efforts from this end. It all feels tantalisingly close, as I said in my earlier post I am really keen for this functionality to be working as I have an immediate use for it.

    Thanks for your efforts

    Paul

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    I've messaged @PaulBeddis directly, but for the thread. I have a fix completed internally and a not-qa bleeding edge build available for testing if you are hitting this. Please message me directly.

  • PaulBeddisPaulBeddis Paul Beddis GBMember

    Chris

    I've tested your special build now and it looks like it fixes the problem I raised originally. Thanks for the early access to that build.

    I've now tried to run the application that references the .Mac binding library, and I get challenged for a license (indie or greater). I do have a business license for the stable Xamarin release that I use daily, but I don't really want to put it on this preview version - is there anything I can do to allow me to run things built in the preview version?

    Paul

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    So I'm assuming the problem is the necessary p/invokes needed to invoke native code.

    Have you considered starting a trial on your second machine? Have you already done that and run out of time?

  • PaulBeddisPaulBeddis Paul Beddis GBMember

    yes you're correct, it's the p/invokes.

    Hadn't thought about starting a second trial (the simple things are the most obvious!), would the rights available through the trial be sufficient?

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    I took a quick glance at the code in question. I think it likely should work.

    I have not spun up a machine with no license to validate it. Let me know how it goes. :)

  • AllanChin.6924AllanChin.6924 Allan Chin USUniversity ✭✭✭

    Hey Chris - for these binding class libraries in general, what is the recommended mechanism for sending events or invoking callback methods across this boundary, up and down? Thanks.

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    So it really depends on what kind of audience you have (1-1 or 1-many), how often it happens, and such. This article has a good breakdown:

    http://nshipster.com/nsnotification-and-nsnotificationcenter/

    Assuming the native piece is objective-c, setting up both sides to use NSNotificationCenter would be trivial, but slow and overkill for the 1-1 use case.

    If you are looking for a 1-1, you could provide a unmanaged method to invoke (either something static directly, or some method on a class/delegate) when you are going "down" to managed.

    Going back "up" to unmanaged is a bit trickier. There are two ways that come to mind. You could pass down some NSObject derived type down to native, and native could invoke some selector (that you [Export]ed from C#), or you could pass down a raw function pointer (by passing a delegate, unsure if you need MonoPInvokeCallbackAttribute off top of my head) and invoke that.

    Let me know if you have further questions.

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    One further note, assuming your native side is objective-c, there is no reason you can't just think of both sides as objective-c. You pass objects up to the managed side and invoke them when necessary. And you can pass managed NSObject derived objects to native to invoke there. Just make sure you get your lifetime right (invoking a disposed C# object from native will cause sadness).

  • DavyBaarsDavyBaars Davy Baars NLMember

    I'm running into some issues when trying to generate a binding for a CocoaPod.
    I've had the following issues when adding a Mac binding project to my solution.
    When the project is added, it tries to save the solution, but this goes on indefinitly. I cannot do any other actions (save manually) because most options are disabled during this saving.

    I worked around this problem as follows:

    1. Removed both the ItemGroups for the ApiDefinition and the StructsAndEnums from the .csproj file.
    2. Loaded the solution using XS 5.10.2 (might as well have worked on 6.0.0)
    3. Re-added the ItemGroups (with correct build setting (ObjcBindingCoreSource and ObjcBindingApiDefinition)
    4. Reload the solution. Project is now correctly loaded.

    After this I still have some remaining problems.

    • .linkwith.cs file was not automatically added when I've added the native file.
    • [Category] and [BaseType(...)] Attributes in the ApiDefinition do not exist in the current context (CS0103) but project build fine.
    • When adding the binding project as a reference the project no longer build because it cannot find the native library. (Library's build action is set to ObjcBindingNativeLibrary)

    The ApiDefinition was generated using Objective Sharpie, as slightly modified. Although I think this file is correct because it has vary simple content.

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    @DavyBaars Hmm. A few thoughts.

    • I believe CS0103 is fixed if you used the XS linked (6.0). If you can reproduce it with that build, let me know.
    • I'll look at the other 3 issues shortly.
    • Could you clean / attach the project in question for me to look at?
  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    At this point, this preview has been obsoleted by the Alpha channel completely. Please use that instead.

  • DRGDRG Dan Guthrie USMember

    I am trying to build Xamarin.Mac bindings for the ORSSerialPort library and running into some issues. Do I still need the Alpha channel or is the needed functionality included in the Xamarin Studio 6.0.2 / Xamarin.Mac 2.8.22? I have successfully (but perhaps not correctly) run sharpie and created the Binding directory but when I bring the two created cs files into a Xamarin.Mac Binding project several of the attributes are unrecognized (NULLALLOWED, STATIC, VERIFY, etc).

    I downloaded the ORSSerialPort project from github and ran the following two commands:

    • sharpie pod init macosx10.11 ORSSerialPort
    • sharpie pod bind ORSSerialPort

    Any idea what I may be doing wrong?

    Thanks,

    Dan

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    @DRG - Please try building. There was/is a bug where the IDE was showing swiggly lines but it build successfully.

    If the build fails for real, please attach the build log and\or the project itself.

  • DRGDRG Dan Guthrie USMember

    "These are not the droids you are looking for"! Thanks.

    I managed to get it to build. My first attempt to use the new library resulted in a "Native class hasn't been..." error. I did some googling and tried recompiling the *.a lib using "Dynamic Library" in the Linking section. I am now receiving "unrecognized selector sent to instance" which I assume is progress...but obviously still something wrong. Any advice is greatly appreciated. I am certainly feeling my way around in the dark on this one.

    Dan

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    Without knowing more about the library in question, I really can't help too much on that issue given what you've said so far. "unrecognized selector sent to instance" is what it says. You called a selector on something that didn't expect it.

    • Maybe your binding is wrong, and the thing you are calling doesn't support it
    • Maybe your library in 32-bit or 64-bit only, and the binary doesn't have symbols for that ?
    • Maybe there is some library specific init that you haven't done yet?
  • DRGDRG Dan Guthrie USMember

    Thanks. The library is called ORSSerialPort and it is an objective-C library used to access serial ports on OS X. The library uses IOKit, which appears to not be listed in the list of Xamarin.Mac supported libraries...is this an issue? I was assuming that since what I am wrapping (ORSSerialPort) makes the calls into IOKit that this would still work....but perhaps I am wrong.

    I really appreciate all of the help and feedback.

    Dan

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    No, that should not matter at all. All the "supported libraries" refer to in our documentation is which libraries we've already written a objective-c -> C# binding. IOKit is not bound directly into C#, but there is no reason you couldn't use a native library that calls into IOKit.

    If you attach a small sample, someone here (or I) would be able to more easily take a look. Well except for the fact that none of my machine even have a serial port :)

  • DRGDRG Dan Guthrie USMember

    Chris

    Thanks for you continued support and guidance. In case anyone stumble across this thread...here is what I found...

    I do not have much experience with Xcode and that was the majority of my issue. When I added a new target to the ORSSerialPort project to create a static library, I did not realize that I had to check all of the files in the inspector on the right to include them in the build...so my static library essentially was empty. The binding project did not throw an error and built fine so I did not realize that there was such a basic and HUGE problem. lol. Once I became a bit more knowledgeable in Xcode things seemed to come together.

    Next...all of this was a waste of time! The .Net SerialPort class DOES exist for Xamarin.Mac...so all of the code that I had for my WPF version of my app could have been reused as it. The problem was in Project Options -> General the Target Framework was set to Xamarin.Mac Mobile Framework. If you select the Xamarin.Mac 4.5 Framework you gain access to System.IO.Ports namespace and most of the Serial Port functionality just works. Be warned there is talk around the inter webs about event driven receive not working. I do not use that aspect of the library so I cannot confirm or deny...but be aware if you do. I simply use Read/Write for the most part.

    I hope someone finds this information useful,

    Dan

Sign In or Register to comment.