应用在启动时关闭 - Xamarin iOS 的 Redpark SDK 绑定

问题描述

我已将本机框架 Redpark Serial SDK 1.0.5 转换为绑定库(名为:redparkBinding)并在我的一个项目中使用它。

我在演练中仔细遵循了每个步骤:Binding an iOS Objective-C Library redparkBinding 项目的构建结果成功。

但是,我面临一个奇怪的问题。应用程序在启动时崩溃(原因:NullReferenceException - 在 sdk 中有一个单例类,它总是为 null)。

enter image description here

更多细节:

  • 这会在调试和发布模式下发生。
  • 支持的架构是 ARM64
  • 链接器行为:仅限链接框架 SDK
  • 原生 SDK 示例完美运行。

我知道库本身按预期工作,因为它也用于本机 iOS 应用程序。我只是想弄清楚我的绑定项目配置中缺少什么。

这是与我的 .a 库关联的源 .h 文件

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN


// DEFAULT VALUES
// baudrate == 9600
// dataConfiguration == kDataConfig_8N1
// enableRtsCtsFlowControl == NO
// enableDtrDsrFlowControl == NO
// enableSoftwareFlowControl == NO
// dtr == FALSE
// rts == FALSE

enum SerialPortDataConfiguration
{
    kDataConfig_8N1,// 8bit,no parity,one stop bit
    kDataConfig_8O1,odd parity,one stop bit
    kDataConfig_8E1,even parity,one stop bit
    kDataConfig_7O1,// 7bit,one stop bit
    kDataConfig_7E1,one stop bit
    kDataConfig_8N2,two stop bits
    kDataConfig_8O2,two stop bits
    kDataConfig_8E2,two stop bits

};

@class RedSerialPort;

@protocol RedSerialPortDelegate  <NSObject>


@optional
// called when serial port's transmit FIFO is empty
-(void) transmitFifoIsEmpty:(RedSerialPort *)thePort;

// called when any of the rx modem signals change state (CTS,DSR,DCD or RI)
// user can check value of each modem signal property to determine current state
// optionally,user can set an observer for the modem signal property interested in
- (void) modemSignalChange:(RedSerialPort *)thePort;

// called when TX or RX Flow Control state changes
- (void) flowControlStateChange:(RedSerialPort *)thePort flowControlIsHalted:(BOOL)isFlowHalted;


@end

@interface RedSerialPort : NSObject
{

}

@property (nonatomic,weak) id <RedSerialPortDelegate> delegate;
@property (readonly) BOOL cts;
@property (readonly) BOOL dsr;
@property (readonly) BOOL dcd;
@property (readonly) BOOL ri;
@property (nonatomic) BOOL dtr;
@property (nonatomic) BOOL rts;
@property (readonly) BOOL isFlowConbtrolHalted;
@property (nonatomic) int baudrate;
@property (nonatomic) enum SerialPortDataConfiguration dataConfiguration;
@property (nonatomic) BOOL enableRtsCtsFlowControl;
@property (nonatomic) BOOL enableDtrDsrFlowControl;
@property (nonatomic) BOOL enableSoftwareFlowControl;

// send NSData bytes over serial connection
// calls sendCompleteBlock when all bytes in the NSData are transferred from UART FIFO
-(BOOL)sendData:(NSData *)data sendDataComplete:(void (^)(void))sendCompleteBlock;

// post a read to the serial port
// recvCompleBlock is called when bytes are received
-(BOOL)recvData:(void (^)(NSData *))recvCompleteBlock;



/* =============================================================*/
enum
{
    kFwUpdataComplete = 0,kFwUpdataInProgress   = 1,kFwUpdataErasingSectors       = 2,kFwUpdataRebootingDevice      = 3,kFwUpdataBadAddress   = 0x81,kFwUpdataVerifyFailed = 0x82,kFwUpdataWriteError   = 0x83,kFwUpdataBadLength    = 0x84,kFwUpdataFlashTimeout = 0x85
    
};

// Check if connected serial device has latest firmware
-(BOOL)isFirmwareCurrent;

// update serial device firmware to latest version
// updateProgressBlock will be called with firmare download progress
// progress is a value 0-100 indicating the percent of file downloaded.
// state = kFwUpdataInProgress - download is in progress.
// state = kFwUpdataComplete - download is complete and was successful
// state = kFwUpdataRebootingDevice - normal expected state during update
// state = kFwUpdataErasingSectors - normal expected state during update
// state = 0x8n - an error occurred during download and was stopped.  Cable was not updated.
-(void)updateFirmware:(void (^)(int progress,uint8_t state))updateProgressBlock;

@end

@protocol RedSerialDeviceManagerDelegate  <NSObject>

//
// called when a device is discovered
//
- (void) deviceDetected:(RedSerialPort *)thePort;

//
// called when device connection is broken,object is Now orphaned
//
- (void) devicedisconnected:(RedSerialPort *)thePort;
@end


@interface RedSerialDeviceManager : NSObject
{
    
}

@property (nonatomic,weak) id <RedSerialDeviceManagerDelegate> delegate;

// return singleton RedSerialDeviceManager
+ (RedSerialDeviceManager *)sharedManager;

// Call to enumerate connected device or register for notifications
// app should call this once at app launch
- (void) startdiscovery;

// application must call this when re-entering foreground to resume communication
// session with accessory
-(void) resume;

// called to clean up existing communication sessions with device
// app must call when going into background
- (void) stop;


@end

NS_ASSUME_NONNULL_END

这里是用sharpie创建的C#关联界面

using System;
using Foundation;
using ObjCRuntime;

namespace redparkLibrary
{
    // @protocol RedSerialPortDelegate <NSObject>
    [Protocol,Model(AutoGeneratedname = true)]
    [BaseType(typeof(NSObject))]
    interface RedSerialPortDelegate
    {
        // @optional -(void)transmitFifoIsEmpty:(RedSerialPort * _Nonnull)thePort;
        [Export("transmitFifoIsEmpty:")]
        void TransmitFifoIsEmpty(RedSerialPort thePort);

        // @optional -(void)modemSignalChange:(RedSerialPort * _Nonnull)thePort;
        [Export("modemSignalChange:")]
        void ModemSignalChange(RedSerialPort thePort);

        // @optional -(void)flowControlStateChange:(RedSerialPort * _Nonnull)thePort flowControlIsHalted:(BOOL)isFlowHalted;
        [Export("flowControlStateChange:flowControlIsHalted:")]
        void FlowControlStateChange(RedSerialPort thePort,bool isFlowHalted);
    }

    // @interface RedSerialPort : NSObject
    [BaseType(typeof(NSObject))]
    interface RedSerialPort
    {
        [Wrap("WeakDelegate")]
        [NullAllowed]
        RedSerialPortDelegate Delegate { get; set; }

        // @property (nonatomic,weak) id<RedSerialPortDelegate> _Nullable delegate;
        [NullAllowed,Export("delegate",ArgumentSemantic.Weak)]
        NSObject WeakDelegate { get; set; }

        // @property (readonly) BOOL cts;
        [Export("cts")]
        bool Cts { get; }

        // @property (readonly) BOOL dsr;
        [Export("dsr")]
        bool Dsr { get; }

        // @property (readonly) BOOL dcd;
        [Export("dcd")]
        bool Dcd { get; }

        // @property (readonly) BOOL ri;
        [Export("ri")]
        bool Ri { get; }

        // @property (nonatomic) BOOL dtr;
        [Export("dtr")]
        bool Dtr { get; set; }

        // @property (nonatomic) BOOL rts;
        [Export("rts")]
        bool Rts { get; set; }

        // @property (readonly) BOOL isFlowConbtrolHalted;
        [Export("isFlowConbtrolHalted")]
        bool IsFlowConbtrolHalted { get; }

        // @property (nonatomic) int baudrate;
        [Export("baudrate")]
        int Baudrate { get; set; }

        // @property (nonatomic) enum SerialPortDataConfiguration dataConfiguration;
        [Export("dataConfiguration",ArgumentSemantic.Assign)]
        SerialPortDataConfiguration DataConfiguration { get; set; }

        // @property (nonatomic) BOOL enableRtsCtsFlowControl;
        [Export("enableRtsCtsFlowControl")]
        bool EnableRtsCtsFlowControl { get; set; }

        // @property (nonatomic) BOOL enableDtrDsrFlowControl;
        [Export("enableDtrDsrFlowControl")]
        bool EnableDtrDsrFlowControl { get; set; }

        // @property (nonatomic) BOOL enableSoftwareFlowControl;
        [Export("enableSoftwareFlowControl")]
        bool EnableSoftwareFlowControl { get; set; }

        // -(BOOL)sendData:(NSData * _Nonnull)data sendDataComplete:(void (^ _Nonnull)(void))sendCompleteBlock;
        [Export("sendData:sendDataComplete:")]
        bool SendData(NSData data,Action sendCompleteBlock);

        // -(BOOL)recvData:(void (^ _Nonnull)(NSData * _Nonnull))recvCompleteBlock;
        [Export("recvData:")]
        bool RecvData(Action<NSData> recvCompleteBlock);

        // -(BOOL)isFirmwareCurrent;
        [Export("isFirmwareCurrent")]
        bool IsFirmwareCurrent { get; }

        // -(void)updateFirmware:(void (^ _Nonnull)(int,uint8_t))updateProgressBlock;
        [Export("updateFirmware:")]
        void UpdateFirmware(Action<int,byte> updateProgressBlock);
    }

    // @protocol RedSerialDeviceManagerDelegate <NSObject>
    [Protocol,Model(AutoGeneratedname = true)]
    [BaseType(typeof(NSObject))]
    interface RedSerialDeviceManagerDelegate
    {
        // @required -(void)deviceDetected:(RedSerialPort * _Nonnull)thePort;
        [Abstract]
        [Export("deviceDetected:")]
        void DeviceDetected(RedSerialPort thePort);

        // @required -(void)devicedisconnected:(RedSerialPort * _Nonnull)thePort;
        [Abstract]
        [Export("devicedisconnected:")]
        void Devicedisconnected(RedSerialPort thePort);
    }

    // @interface RedSerialDeviceManager : NSObject
    [BaseType(typeof(NSObject))]
    interface RedSerialDeviceManager
    {
        [Wrap("WeakDelegate")]
        [NullAllowed]
        RedSerialDeviceManagerDelegate Delegate { get; set; }

        // @property (nonatomic,weak) id<RedSerialDeviceManagerDelegate> _Nullable delegate;
        [NullAllowed,ArgumentSemantic.Weak)]
        NSObject WeakDelegate { get; set; }

        // +(RedSerialDeviceManager * _Nonnull)sharedManager;
        [Static]
        [Export("sharedManager")]
        RedSerialDeviceManager SharedManager { get; }

        // -(void)startdiscovery;
        [Export("startdiscovery")]
        void Startdiscovery();

        // -(void)resume;
        [Export("resume")]
        void Resume();

        // -(void)stop;
        [Export("stop")]
        void Stop();
    }

    // @interface redparkBinding : NSObject
    [BaseType(typeof(NSObject))]
    interface redparkBinding
    {
    }
}

这是 .a 文件的 LinkWith 选项 [assembly: LinkWith("libredparkBinding.a”,SmartLink = true,ForceLoad = true)]

和 Makefile 文件

XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=./redparkBinding
PROJECT=$(PROJECT_ROOT)/redparkBinding.xcodeproj
TARGET=redparkBinding

all: lib$(TARGET).a

lib$(TARGET)-arm64.a:
    $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch arm64 -configuration Release clean build
    -mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@

lib$(TARGET).a: lib$(TARGET)-arm64.a
    xcrun -sdk iphoneos lipo -create -output $@ $^

clean:
    -rm -f *.a *.dll

此外,我还在此处附上了所有必需的 files(本机库框架、本机库示例代码、绑定代码、SDK 用户指南)。

感谢来自社区的任何建议。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...