Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin: Binding ios protocol/delegate can't access enum defined in structs.cs

I'm currently in the process of creating ios bindings for the EDQueue library.

The Structs.cs file looks something like this:

using System;
using ObjCRuntime;

namespace EDQueue
{


    // => Enums attributed with[NativeAttribute] must have an underlying type of `long` or `ulong`
    [Native]
    public enum EDQueueResult : long
    {
        Success = 0,
        Fail,
        Critical
    }

}

The ApiDefinition.cs file is something like:

using System;
using Foundation;
using ObjCRuntime;

namespace EDQueue
{
    // typedef void (^EDQueueCompletionBlock)(EDQueueResult);
    delegate void EDQueueCompletionBlock(EDQueueResult result);

    // ETC....

    // @protocol EDQueueDelegate <NSObject>
    [Protocol, Model]
    [BaseType(typeof(NSObject))]
    interface EDQueueDelegate
    {
        // @optional -(EDQueueResult)queue:(EDQueue *)queue processJob:(NSDictionary *)job;
        [Export("queue:processJob:")]
        EDQueueResult Queue(EDQueue queue, NSDictionary job);

        //// @optional -(void)queue:(EDQueue *)queue processJob:(NSDictionary *)job completion:(EDQueueCompletionBlock)block;
        //[Export("queue:processJob:completion:")]
        //void Queue(EDQueue queue, NSDictionary job, EDQueueCompletionBlock completeBlock);

    }

    // ETC...
}

As written, the following error is produced: Error CS0426: The type name 'EDQueueResult' does not exist in the type 'EDQueue' (CS0426) (EDQueue) in file EDQueueDelegate.g.cs

That file looks like this when the error is thrown:

//
// Auto-generated from generator.cs, do not edit
//
// We keep references to objects, so warning 414 is expected

#pragma warning disable 414

using System;
using System.Drawing;
using System.Diagnostics;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using UIKit;
using GLKit;
using Metal;
using MapKit;
using ModelIO;
using SceneKit;
using Security;
using AudioUnit;
using CoreVideo;
using CoreMedia;
using QuickLook;
using Foundation;
using CoreMotion;
using ObjCRuntime;
using AddressBook;
using CoreGraphics;
using CoreLocation;
using AVFoundation;
using NewsstandKit;
using CoreAnimation;
using CoreFoundation;

namespace EDQueue {
    [Protocol (Name = "EDQueueDelegate", WrapperType = typeof (EDQueueDelegateWrapper))]
    [ProtocolMember (IsRequired = false, IsProperty = false, IsStatic = false, Name = "Queue", Selector = "queue:processJob:", ReturnType = typeof (EDQueue.EDQueueResult), ParameterType = new Type [] { typeof (global::EDQueue.EDQueue), typeof (NSDictionary) }, ParameterByRef = new bool [] { false, false })]
    public interface IEDQueueDelegate : INativeObject, IDisposable
    {
    }
// ETC...
}

However, if I remove or comment out the [Protocol, Model] bit, the library builds without error.

I'm also getting a similar error if I uncomment the second function with the EDQueueCompletionBlock, which ultimately relies on the EDQueueResult enum.

The Structs.cs file's build action is set to ObjcBindingCoreSource.

Any help is truly appreciated. Thanks!

like image 775
astjohn Avatar asked May 14 '17 17:05

astjohn


1 Answers

Since you have both namespace EDQueue and type (interface) named EDQueue - you cannot reference any type in namespace EDQueue with EDQueue.TypeName, so this statement:

ReturnType = typeof (EDQueue.EDQueueResult)

Will not compile, because compiler will search for a member inside EDQueue interface (even though interfaces cannot have child classes, nor static members) and not inside EDQueue namespace.

Most obvious way to fix this is to not ever have namespace and type with the same name, so rename either namespace or type name.

If that is not possible or you are not completely sure it will not have side effects - change reference to

ReturnType = typeof (EDQueueResult)

and add using EDQueue to the usings block. Alternatively, reference like this:

ReturnType = typeof (global::EDQueue.EDQueueResult)
like image 74
Evk Avatar answered Nov 19 '22 10:11

Evk