1

Socket Mobile の SocketScan SDK を使用する Xamarin ios アプリケーションを作成しています。スタティック ライブラリを dll に変換する Binding プロジェクトを作成しました。ただし、SktClassFactory.CreateScanObject () メソッドを使用して ISktScanObject のインスタンスを作成することはできません。System.MemberAccessException が原因で、インスタンスが完全に作成されていません。以下のコードをご覧ください

// A 1:1 of ApiHelper's Objective-C open: method
public void Open ()
{
    _deviceInfoList.Clear ();

    if (_noDeviceText != null) {
        _deviceInfoList.Add (_noDeviceText, _noDeviceText);
    }

    if (_scanObjectReceived != null) {
        SktClassFactory.ReleaseScanObject (_scanObjectReceived);
    }
    _scanObjectReceived = SktClassFactory.CreateScanObject (); //Two properties inside _scanObjectReceived are not getting created due to System.MemberAccessException. 

    Task.Run (() => InitializeScanAPIThread ());

    _scanApiOpen = true;
}

以下は、行 _scanObjectReceived = SktClassFactory.CreateScanObject (); の後に _scanObjectReceived オブジェクトをデバッグするときに表示される例外メッセージです。

  1. メッセージ System.MemberAccessException: 抽象クラスであるため、ScanAPI.ISktScanMsg のインスタンスを作成できません
  2. プロパティ System.MemberAccessException: 抽象クラスであるため、ScanAPI.SktScanProperty のインスタンスを作成できません

バインド プロジェクトの ISktScanObject インターフェイスの ApiDefinition は次のとおりです。

[Protocol, Model]    
interface ISktScanObject {}

// @protocol ISktScanObject
[Protocol, Model]
[BaseType (typeof (NSObject))]
interface SktScanObject : ISktScanObject
{
    // @required -(id<ISktScanMsg>)Msg;
    [Abstract]
    [Export ("Msg")]
    ISktScanMsg Msg { get; }

    // @required -(id<ISktScanProperty>)Property;
    [Abstract]
    [Export ("Property")]
    SktScanProperty Property { get; }
} 

バインド プロジェクトの SktClassFactory インターフェイスの ApiDefinition は次のとおりです。

[BaseType (typeof(NSObject))]
interface SktClassFactory
{
    // +(id<ISktScanObject>)createScanObject;
    [Static]
    [Export ("createScanObject")]
    ISktScanObject CreateScanObject ();

    // +(void)releaseScanObject:(id<ISktScanObject>)scanObj;
    [Static]
    [Export ("releaseScanObject:")]
    void ReleaseScanObject (ISktScanObject scanObj);

    // +(id<ISktScanApi>)createScanApiInstance;
    [Static]
    [Export ("createScanApiInstance")]
    ISktScanApi CreateScanApiInstance ();

    // +(void)releaseScanApiInstance:(id<ISktScanApi>)scanApi;
    [Static]
    [Export ("releaseScanApiInstance:")]
    void ReleaseScanApiInstance (ISktScanApi scanApi);

    // +(id<ISktScanDevice>)createDeviceInstance:(id<ISktScanApi>)scanApi;
    [Static]
    [Export ("createDeviceInstance:")]
    ISktScanDevice CreateDeviceInstance (ISktScanApi scanApi);

    // +(void)releaseDeviceInstance:(id<ISktScanDevice>)deviceInstance;
    [Static]
    [Export ("releaseDeviceInstance:")]
    void ReleaseDeviceInstance (ISktScanDevice deviceInstance);
} 

_scanObjectReceived オブジェクトを適切にインスタンス化するために必要なこと。前もって感謝します。

4

2 に答える 2

1

これはかなり遅れているかもしれませんが、現在の API を使用して iOS バインディングを作成し、次を使用して ISktScanObject と ISktScanApi を呼び出すことができました。

ScanObject = SktClassFactory.CreateScanObject;
ScanApi = SktClassFactory.CreateScanApiInstance;

これにより、抽象クラスに関する問題は発生しませんでした。

SktClassFactory の私の ApiDefinition は次のようになります。

// @interface SktClassFactory : NSObject
[BaseType (typeof(NSObject))]
interface SktClassFactory
{
    // +(ISktScanObject *)createScanObject;
    [Static]
    [Export ("createScanObject")]
    ISktScanObject CreateScanObject { get; }

    // +(void)releaseScanObject:(ISktScanObject *)scanObj;
    [Static]
    [Export ("releaseScanObject:")]
    void ReleaseScanObject (ISktScanObject scanObj);

    // +(ISktScanApi *)createScanApiInstance;
    [Static]
    [Export ("createScanApiInstance")]
    ISktScanApi CreateScanApiInstance { get; }

    // +(void)releaseScanApiInstance:(ISktScanApi *)scanApi;
    [Static]
    [Export ("releaseScanApiInstance:")]
    void ReleaseScanApiInstance (ISktScanApi scanApi);

    // +(ISktScanDevice *)createDeviceInstance:(ISktScanApi *)scanApi;
    [Static]
    [Export ("createDeviceInstance:")]
    ISktScanDevice CreateDeviceInstance (ISktScanApi scanApi);

    // +(void)releaseDeviceInstance:(ISktScanDevice *)deviceInstance;
    [Static]
    [Export ("releaseDeviceInstance:")]
    void ReleaseDeviceInstance (ISktScanDevice deviceInstance);
}

編集: 私の ISktScanObject は、ApiDefinition で次のようになります。

// @interface ISktScanObject : NSObject
[BaseType (typeof(NSObject))]
interface ISktScanObject
{
    // -(ISktScanMsg *)Msg;
    [Export ("Msg")]
    ISktScanMsg Msg { get; }

    // -(ISktScanProperty *)Property;
    [Export ("Property")]
    ISktScanProperty Property { get; }
}

これがお役に立てば幸いです。

于 2015-11-23T16:53:01.007 に答える
0

あなたが をバインドしていることがわかります@protocol。フィリップスの回答では、SDK が@interfaceこのタイプの を使用するように変更されたため、彼の回答はあまり明確ではありません。

ライブラリがインスタンス化できなかった戻り値の型にスケルトン インターフェイス (空のインターフェイス) を追加し、すべての戻り値の型とパラメーターの型をクラスからインターフェイス名に変更することで、(別のライブラリで) 問題を修正しました。

追加されたインターフェイスと変更された戻り値の型に注意してください。

// @protocol NXProximityZone <NSObject>
[Protocol, Model]
[BaseType(typeof(NSObject))]
interface NXProximityZone
{
    // Methods and properties removed for simplicity
}

// @interface NXProximityManager : NSObject
[BaseType(typeof(NSObject))]
interface NXProximityManager
{
    // +(NSObject<NXProximityZone> *)proximityZoneFromNotification:(NSNotification *)notification;
    [Static]
    [Export("proximityZoneFromNotification:")]
    NXProximityZone ProximityZoneFromNotification(NSNotification notification);

    // Methods and properties removed for simplicity
}

// @protocol NXProximityZone <NSObject>
[Protocol, Model]
[BaseType(typeof(NSObject))]
interface NXProximityZone
{
    // Methods and properties removed for simplicity
}

// Skeleton interface
interface INXProximityZone { }

// @interface NXProximityManager : NSObject
[BaseType(typeof(NSObject))]
interface NXProximityManager
{
    // +(NSObject<NXProximityZone> *)proximityZoneFromNotification:(NSNotification *)notification;
    [Static]
    [Export("proximityZoneFromNotification:")]
    INXProximityZone ProximityZoneFromNotification(NSNotification notification);

    // Methods and properties removed for simplicity
}

スケルトン インターフェイスの詳細については、こちらを参照してください (スケルトンのページを検索してください)。

于 2017-01-31T09:43:55.650 に答える