【问题标题】:Xamarin - error building a binding library Messaging.g.csXamarin - 错误构建绑定库 Messaging.g.cs
【发布时间】:2016-09-24 12:30:15
【问题描述】:

在为 Xamarin.iOS 构建绑定库时遇到问题。基本上我需要构建它以将dll 引用到一个单独的项目中。

这是我的示例project

问题是自动生成的Messaging.g.cs 出现错误并完成中线:

//
// 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 Security;
using SceneKit;
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 ApiDefinition {
    partial class Messaging {
        static internal System.Reflection.Assembly this_assembly = typeof (Messaging).Assembly;

        const string LIBOBJC_DYLIB = "/usr/lib/libobjc.dylib";

        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static IntPtr IntPtr_objc_msgSend (IntPtr receiever, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static IntPtr IntPtr_objc_msgSendSuper (IntPtr receiever, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static IntPtr IntPtr_objc_msgSend_IntPtr (IntPtr receiever, IntPtr selector, IntPtr arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static IntPtr IntPtr_objc_msgSendSuper_IntPtr (IntPtr receiever, IntPtr selector, IntPtr arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static void void_objc_msgSend_IntPtr (IntPtr receiver, IntPtr selector, IntPtr arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static void void_objc_msgSendSuper_IntPtr (IntPtr receiver, IntPtr selector, IntPtr arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static int int_objc_msgSend (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static int int_objc_msgSendSuper (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static void void_objc_msgSend_int (IntPtr receiver, IntPtr selector, int arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static void void_objc_msgSendSuper_int (IntPtr receiver, IntPtr selector, int arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static float float_objc_msgSend (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static float float_objc_msgSendSuper (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static void void_objc_msgSend_float (IntPtr receiver, IntPtr selector, float arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static void void_objc_msgSendSuper_float (IntPtr receiver, IntPtr selector, float arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static bool bool_objc_msgSend (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static bool bool_objc_msgSendSuper (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static void void_objc_msgSend_bool (IntPtr receiver, IntPtr selector, bool arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static void void_objc_msgSendSuper_bool (IntPtr receiver, IntPtr selector, bool arg1);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static global::System.Double Double_objc_msgSend (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSendSuper")]
        public extern static global::System.Double Double_objc_msgSendSuper (IntPtr receiver, IntPtr selector);
        [DllImport (LIBOBJC_DYLIB, EntryPoint="objc_msgSend")]
        public extern static void vo

我还关注了Xamarin的官方演练。

我正在尝试构建的项目的原始 repo 是 here,它是原始 Objectice-C here 的绑定项目。

我无法弄清楚为什么 Messaging.g.cs 会出错并阻止构建完成。

任何帮助将不胜感激。

一切顺利,

约翰

【问题讨论】:

    标签: ios xamarin binding build swrevealviewcontroller


    【解决方案1】:

    我已经设法解决了这个问题。

    我希望这个答案在未来对其他 Xamarin 开发人员有所帮助。

    如果您使用的是 Objective C 绑定库,则应使用 XCode 构建并使用 Objective Sharpie 可用的 here 生成 ApiDefinition.cs 和 StructsAndEnums.cs。

    我遇到的问题是自动生成的代码无法正确处理Delegates。此外,[Native] 属性导致解释器使用不兼容的数据类型 - 即 enum 结构与 uint

    结合上述问题,我还尝试在同一个项目中绑定多个.a 静态库。

    因此,您需要在 Objective Sharpie 生成的 C# 文件中重构一些内容:

    删除任何重复的方法签名在我的示例中,该工具生成了以下代码:

            // @optional -(BOOL)revealControllerPanGestureShouldBegin:(SWRevealViewController *)revealController;
            [Export("revealControllerPanGestureShouldBegin:")]
            bool RevealController(SWRevealViewController revealController);
    
            // @optional -(BOOL)revealControllerTapGestureShouldBegin:(SWRevealViewController *)revealController;
            [Export("revealControllerTapGestureShouldBegin:")]
            bool RevealController(SWRevealViewController revealController);
    

    而为了避免编译器抛出重复的方法错误,它应该是:

            // @optional -(BOOL)revealControllerPanGestureShouldBegin:(SWRevealViewController *)revealController;
            [Export("revealControllerPanGestureShouldBegin:")]
            bool RevealControllerPanGestureShouldBegin(SWRevealViewController revealController);
    
            // @optional -(BOOL)revealControllerTapGestureShouldBegin:(SWRevealViewController *)revealController;
            [Export("revealControllerTapGestureShouldBegin:")]
            bool RevealControllerTapGestureShouldBegin(SWRevealViewController revealController);
    

    接下来,查找工具生成枚举结构的任何示例,该结构继承自不受支持的原语。

    所以,例如:

    [Native]
    public enum FrontViewPosition : uint
    {
        LeftSideMostRemoved,
        LeftSideMost,
        LeftSide,
        Left,
        Right,
        RightMost,
        RightMostRemoved
    }
    

    更改为public enum FrontViewPosition : ulong

    接下来删除任何[Verify] 装饰。

    最后,我发现Objective Sharpie对扩展方法的处理很差,导致生成的代码试图创建一个内部带有虚拟方法的静态类......

    要修复,请查找[Category] 的所有实例,例如:

    // @interface SWRevealViewController (UIViewController)
    [Category]
    [BaseType(typeof(UIViewController))]
    partial interface UIViewController_SWRevealViewController
    {
        // -(SWRevealViewController *)revealViewController;
        [Export("revealViewController")]
        SWRevealViewController RevealViewController{ get; };
    }
    

    把它改成

    // @interface SWRevealViewController (UIViewController)
    [Category]
    [BaseType(typeof(UIViewController))]
    partial interface UIViewController_SWRevealViewController
    {
        // -(SWRevealViewController *)revealViewController;
        [Export("revealViewController")]
        SWRevealViewController RevealViewController();
    }
    

    现在清理并重建,自动生成的代码现在将正确编译。在任何需要的项目中引用绑定 dll 以使用它。

    如果有人想在 Xamarin 中使用 SWRevealViewController 库,那么为了节省您的时间,您可以使用我的 repo here

    祝你好运,玩得开心。

    约翰

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多