Xamarin.iOS绑定库/本机框架 [英] Xamarin.iOS Binding Libraries / Native Frameworks

查看:135
本文介绍了Xamarin.iOS绑定库/本机框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于某种原因,我需要使用 我的 Xamarin.iOS 应用中的本机框架,问题来了,我不知道如何正确进行绑定.

For some reason i need to use this native framework in my Xamarin.iOS app and the problem comes, that i have no idea how to make bindings properly.

据我所知,该框架还使用了另一个 框架 我有点困惑,我到底需要做什么?

So as i understood correctly, this framework also uses another one framework and i'm little bit confused, what exactly i need to do?

  1. 我是否需要实现静态库(这可能与 本地框架 一起实现),如为也使用另一个框架的本机框架进行绑定,或者我需要分别实现它们?
  2. 也许我应该将所有这些本机框架重新编写为 C# 版本?! (但是这里出现了另一个问题,框架使用 ObjC ,很难在我的 C# 中复制)
  3. 实现我的目标的最佳方法是什么?(也许没有描述,您可以告诉我更多信息).
  1. Do i need to implement static library(is this possible to do with native frameworks) as it shows on official documentation of Xamarin ?
  2. Can i make bindings for native framework that is using another framework too or i need to implement them separately?
  3. Maybe i should re-write all these native frameworks into C# version?!? (But here's appears another problem, frameworks uses ObjC and is hard to reproduce in C# for me)
  4. What is the best approach to achieve my goal?(maybe its not described and you can tell me more).

有什么建议吗?谢谢!

推荐答案

好,最后我做了一个静态库,但是出了点问题,我不能在上使用它模拟器. :(

OK, finally i have made a Static Library, but something is going wrong and i can't use it on Emulator at current moment. :(

我将逐步说明如何制作静态库:

I will explain step by step how i have made an static library :

  • 我从存储库中获取了所有源文件./li>
  • Xcode IDE中,我创建了 Static Library项目 ,此后,我复制了所有从资源库到我的项目的源文件.

  • I got all source files from this repository.
  • In Xcode IDE i have made Static Library project and after this i have copied all source files from repository to my project.

通过迦太基我已经下载了 此框架 (如我所解释的,源文件使用此框架),并且我还在 Build Phases (构建阶段)-> 复制文件 strong>(我已在其中选择框架的地方)放入我的 静态库 中.并成功构建(在 部署目标 10.2上)

Via Carthage i have download this framework(As i have explained, source files uses this framework) and also i have added new category in Build Phases -> Copy Files (where i have selected framework) into my Static Library . And builded successfully(On Deployment Target 10.2)

.

接下来,我制作了 MakeFile ,并成功生成了四个 Fat Binary .a 库,其中没有任何问题.

Next, i have made MakeFile and successfully generated four Fat Binary .a library's without any problem.

Xcrun 命令显示:

Xcrun command shows :

 xcrun -sdk iphoneos lipo -info libOSMapKitAdapter.a
 Architectures in the fat file: libOSMapKitAdapter.a are: i386 armv7 x86_64 arm64

  • 然后我在Xamarin中创建了 绑定库 项目,并添加了 Fat Binary Static Library 作为 本地参考 (我将在下面显示我的.csproj文件),并且我将相同的框架(已复制到项目路径中)放入了 静态库 (也许是多余的?)

    • Then i have created Binding Library project in Xamarin and added Fat Binary Static Library as Native Reference(i will show my .csproj file below) and also i have put the same for framework(i have copied inside to project path) that is linked inside of Static Library (maybe it's redundant?)


      另外,我还用代码


      Also , i have made additional file that is called OSTransformation.framework.linkwith.cs with code:

      • 通过 客观Sharpie 我已经生成了 ApiDefinition.cs Structs.cs . 命令:

      sharpie bind --output=OSMapKitAdapter --namespace=OSMapKitAdapter --sdk=iphoneos10.2 /MyPath/OSMapKitAdapter/OSMapKitAdapter/*.h

      结果是:

      Parsing 5 header files...
      
      Binding...
        [write] ApiDefinitions.cs
        [write] StructsAndEnums.cs
      
      Binding Analysis:
        Automated binding is complete, but there are a few APIs which have been flagged with [
        Verify] attributes. While the entire binding should be audited for best API design
        practices, look more closely at APIs with the following Verify attribute hints:
      
        ConstantsInterfaceAssociation (1 instance):
          There's no foolproof way to determine with which Objective-C interface an extern
          variable declaration may be associated. Instances of these are bound as [Field]
          properties in a partial interface into a nearby concrete interface to produce a more
          intuitive API, possibly eliminating the 'Constants' interface altogether.
      
        PlatformInvoke (4 instances):
          In general P/Invoke bindings are not as correct or complete as Objective-C bindings (
          at least currently). You may need to fix up the library name (it defaults to '__
          Internal') and return/parameter types manually to conform to C calling conventionsfor
          the target platform. You may find you don't even want to expose the C API in your
          binding, but if you do, you'll probably also want to relocate the definition to a
          more appropriate class and expose a stronger type-safe wrapper. For P/Invoke guidance,
           see http://www.mono-project.com/docs/advanced/pinvoke/.
      
        Once you have verified a Verify attribute, you should remove it from the binding source
        code. The presence of Verify attributes intentionally cause build failures.
      
        For more information about the Verify attribute hints above, consult the Objective
        Sharpie documentation by running 'sharpie docs' or visiting the following URL:
      
          http://xmn.io/sharpie-docs
      
      Submitting usage data to Xamarin...
        Submitted - thank you for helping to improve Objective Sharpie!
      
      Done.
      

      ApiDefinition.cs 的生成代码如下:

      [Static]
          [Verify (ConstantsInterfaceAssociation)]
          partial interface Constants
          {
              // extern double OSMapKitAdapterVersionNumber;
              [Field ("OSMapKitAdapterVersionNumber", "__Internal")]
              double OSMapKitAdapterVersionNumber { get; }
      
              // extern const unsigned char [] OSMapKitAdapterVersionString;
              [Field ("OSMapKitAdapterVersionString", "__Internal")]
              byte[] OSMapKitAdapterVersionString { get; }
          }
      
          // @interface OSTileOverlay : MKTileOverlay
          [BaseType (typeof(MKTileOverlay))]
          interface OSTileOverlay
          {
              // @property (assign, nonatomic) BOOL clipOverlay;
              [Export ("clipOverlay")]
              bool ClipOverlay { get; set; }
      
              // -(instancetype _Nonnull)initWithAPIKey:(NSString * _Nonnull)apiKey product:(OSMapProduct)product __attribute__((objc_designated_initializer));
              [Export ("initWithAPIKey:product:")]
              [DesignatedInitializer]
              IntPtr Constructor (string apiKey, OSMapProduct product);
          }
      
          // @interface OSMapViewRegionRestriction : NSObject
          [BaseType (typeof(NSObject))]
          interface OSMapViewRegionRestriction
          {
              // @property (readonly, nonatomic) MKCoordinateRegion initialRegion;
              [Export ("initialRegion")]
              MKCoordinateRegion InitialRegion { get; }
      
              // -(void)updateMapViewRegionIfRequired:(MKMapView * _Nonnull)mapView;
              [Export ("updateMapViewRegionIfRequired:")]
              void UpdateMapViewRegionIfRequired (MKMapView mapView);
          }
      
          // @interface OSMapKitAdapter : NSObject
          [BaseType (typeof(NSObject))]
          interface OSMapKitAdapter
          {
          }
      

      Structs.cs :

      Structs.cs :

      [Native]
      public enum OSMapProduct : nint
      {
          Road,
          Outdoor,
          Light,
          Night
      }
      
      static class CFunctions
      {
          // extern NSString * NSStringFromOSMapProduct (OSMapProduct product);
          [DllImport ("__Internal")]
          [Verify (PlatformInvoke)]
          static extern NSString NSStringFromOSMapProduct (OSMapProduct product);
      
          // extern CLLocationCoordinate2D OSUpperLeftCorner ();
          [DllImport ("__Internal")]
          [Verify (PlatformInvoke)]
          static extern CLLocationCoordinate2D OSUpperLeftCorner ();
      
          // extern CLLocationCoordinate2D OSLowerRightCorner ();
          [DllImport ("__Internal")]
          [Verify (PlatformInvoke)]
          static extern CLLocationCoordinate2D OSLowerRightCorner ();
      
          // extern MKMapRect OSMapRectForUK ();
          [DllImport ("__Internal")]
          [Verify (PlatformInvoke)]
          static extern MKMapRect OSMapRectForUK ();
      }
      

      好的,现在我遇到了编译错误,并且显示Xamarin绑定的官方教程,我需要使用 [Verify] 属性并在解决后检查 Fields 他们遇到的问题需要删除此属性,还需要添加 Protocol 属性等.

      OK, now i got compile errors and as it shows on official tutorial of Xamarin bindings , i need to check Fields with [Verify] Attribute and after resolving problem with them needs to remove this Attribute , also add Protocol attribute and etc.

      ApiDefinition.cs 的新版本:

         [Static]
          //[Verify(ConstantsInterfaceAssociation)]
          partial interface Constants
          {
              // extern double OSMapKitAdapterVersionNumber;
              [Field("OSMapKitAdapterVersionNumber", "__Internal")]
              double OSMapKitAdapterVersionNumber { get; }
      
              // extern const unsigned char [] OSMapKitAdapterVersionString;
              [Field("OSMapKitAdapterVersionString", "__Internal")]
              IntPtr OSMapKitAdapterVersionString { get; }
          }
      
          // @interface OSTileOverlay : MKTileOverlay
          [BaseType(typeof(MKTileOverlay))]
          [Protocol]
          interface OSTileOverlay
          {
              // @property (assign, nonatomic) BOOL clipOverlay;
              [Export("clipOverlay")]
              bool ClipOverlay { get; set; }
      
              // -(instancetype _Nonnull)initWithAPIKey:(NSString * _Nonnull)apiKey product:(OSMapProduct)product __attribute__((objc_designated_initializer));
              [Export("initWithAPIKey:product:")]
              [DesignatedInitializer]
              IntPtr Constructor(string apiKey, OSMapProduct product);
          }
      
          // @interface OSMapViewRegionRestriction : NSObject
          [BaseType(typeof(NSObject))]
          [Protocol]
          interface OSMapViewRegionRestriction
          {
              // @property (readonly, nonatomic) MKCoordinateRegion initialRegion;
              [Export("initialRegion")]
              MKCoordinateRegion InitialRegion { get; }
      
              // -(void)updateMapViewRegionIfRequired:(MKMapView * _Nonnull)mapView;
              [Export("updateMapViewRegionIfRequired:")]
              void UpdateMapViewRegionIfRequired(MKMapView mapView);
          }
      
          // @interface OSMapKitAdapter : NSObject
          [BaseType(typeof(NSObject))]
          [Protocol]
          interface OSMapKitAdapter
          {
          }
      

      结构的新版本:

      #if __UNIFIED__
      [Native]
      public enum OSMapProduct : long
      {
          Road,
          Outdoor,
          Light,
          Night
      }
      #endif 
      static class CFunctions
      {
          // extern NSString * NSStringFromOSMapProduct (OSMapProduct product);
          [DllImport ("__Internal")]
          //[Verify (PlatformInvoke)]
          static extern NSString NSStringFromOSMapProduct (OSMapProduct product);
      
          // extern CLLocationCoordinate2D OSUpperLeftCorner ();
          [DllImport ("__Internal")]
          //[Verify (PlatformInvoke)]
          static extern CLLocationCoordinate2D OSUpperLeftCorner ();
      
          // extern CLLocationCoordinate2D OSLowerRightCorner ();
          [DllImport ("__Internal")]
          //[Verify (PlatformInvoke)]
          static extern CLLocationCoordinate2D OSLowerRightCorner ();
      
          // extern MKMapRect OSMapRectForUK ();
          [DllImport ("__Internal")]
          //[Verify (PlatformInvoke)]
          static extern MKMapRect OSMapRectForUK ();
      }
      

      问题是我遇到此错误:

      错误MT5214:本机链接失败,未定义符号:_OSMapKitAdapterVersionNumber.此符号由托管成员OSTest.Constants.OSMapKitAdapterVersionNumber引用.请确认已引用了所有必要的框架,并且已链接本机库. (MT5214)

      Error MT5214: Native linking failed, undefined symbol: _OSMapKitAdapterVersionNumber. This symbol was referenced by the managed member OSTest.Constants.OSMapKitAdapterVersionNumber. Please verify that all the necessary frameworks have been referenced and native libraries linked. (MT5214)

      错误MT5214:本机链接失败,未定义符号:_OSMapKitAdapterVersionString.此符号由托管成员OSTest.Constants.OSMapKitAdapterVersionString引用.请确认已引用了所有必要的框架,并且已链接本机库. (MT5214)

      Error MT5214: Native linking failed, undefined symbol: _OSMapKitAdapterVersionString. This symbol was referenced by the managed member OSTest.Constants.OSMapKitAdapterVersionString. Please verify that all the necessary frameworks have been referenced and native libraries linked. (MT5214)

      错误MT5202:本机链接失败.请查看构建日志. (MT5202)

      Error MT5202: Native linking failed. Please review the build log. (MT5202)

      我的 _ Xamarin.Bindings _ 项目的 .csproj 文件的外观如何:

      How looks my .csproj file of_ Xamarin.Bindings_ project :

       <ItemGroup>
          <Reference Include="System" />
          <Reference Include="Xamarin.iOS" />
        </ItemGroup>
        <ItemGroup>
          <Compile Include="Properties\AssemblyInfo.cs" />
          <Compile Include="OSTransformation.framework.linkwith.cs" />
        </ItemGroup>
        <ItemGroup>
          <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
        </ItemGroup>
        <ItemGroup>
          <ObjcBindingCoreSource Include="Structs.cs" />
        </ItemGroup>
        <ItemGroup>
          <NativeReference Include="OSTransformation.framework">
            <IsCxx>False</IsCxx>
            <Kind>Framework</Kind>
       </NativeReference>
            <NativeReference Include="..\..\..\MyPath\OSMapKitAdapter\libOSMapKitAdapter.a">
              <Kind>Static</Kind>
              <SmartLink>False</SmartLink>
            </NativeReference>
        </ItemGroup>
        <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.ObjCBinding.CSharp.targets" />
      </Project>
      

      在实际设备上为 WORKS ,但在模拟器上仍然会收到一些奇怪的错误.

      It WORKS on real device, but on emulator still get errors this strange errors.

      只需确保已在链接器上选择仅链接框架SDK",并且可以例外工作!

      Just make sure that you have choose "Link framework SDK only" on linker and works as excepted!

      这篇关于Xamarin.iOS绑定库/本机框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆