При привязке iOS lib.a для Xamarin у меня появляется следующая ошибка:
btouch: The delegate method Device.SomeDeviceDelegate.CaptureComplete needs to take at least one parameter (BI1003)
Были созданы привязки Objective Sharpie.
namespace Device
{
// @protocol SomeDeviceDelegate <NSObject>
[Protocol, Model, Preserve]
[BaseType(typeof(NSObject))]
interface SomeDeviceDelegate
{
// @optional -(void)CaptureComplete;
[Export("CaptureComplete")]
void CaptureComplete();
}
// @interface SomeDevice : NSObject
[Protocol, Model, Preserve]
[BaseType(typeof(NSObject), Delegates = new[] { "WeakDelegate" }, Events = new[] { typeof(SomeDeviceDelegate) })]
interface SomeDevice
{
[Wrap("WeakDelegate")]
SomeDeviceDelegate Delegate { get; set; }
// @property (assign, nonatomic) id<SomeDeviceDelegate> delegate;
[NullAllowed, Export("delegate", ArgumentSemantic.Assign)]
SomeDeviceDelegate WeakDelegate { get; set; }
}
}
NB. Я сменил имя на SomeDevice
чтобы скрыть имя устройства/устройства (NDA).
Компилятор жалуется, что //@optional -(void)CaptureComplete;
и соответствующее связывание CaptureComplete()
не имеет параметров и что ему требуется хотя бы один.
В: Что мне нужно сделать, чтобы связать этот делегат?
Я попробовал Справочное руководство по типам привязок и попытался применить
EventArgs
NoDefaultValue
DefaultValueFromArgument
ОБНОВИТЬ
Я неправильно понял NoDefaultValue
и DefaultValueFromArgument
, они используются, когда делегат возвращает значение (например, bool
), поскольку возврат мешает обертыванию события Xamarin.
Я нашел решение поздно вечером и закрыл этот вопрос для тех, кто сталкивается с тем же сообщением об ошибке.
NB: На этот раз не изменились имена, так как они сделали ответ менее ясным.
Предпочтительный способ обработки делегата ObjC состоит в том, чтобы разоблачить их как События, например
// @interface ICBarCodeReader : ICISMPDevice
[DisableDefaultCtor]
[BaseType(typeof(ICISMPDevice), Delegates = new[] { "WeakDelegate" }, Events = new[] { typeof(ICBarCodeReaderDelegate) }))]
public interface ICBarCodeReader
{
[Wrap("WeakDelegate")]
ICBarCodeReaderDelegate Delegate { get; set; }
// @property (assign, nonatomic) id<ICISMPDeviceDelegate,ICBarCodeReaderDelegate> delegate;
[NullAllowed, Export("delegate", ArgumentSemantic.Assign)]
ICBarCodeReaderDelegate WeakDelegate { get; set; }
}
Параметр Delegate и Events BaseType генерирует коды, которые обертывают каждый метод в ICBarCodeReaderDelegate.
// @protocol ICBarCodeReaderDelegate
[Protocol, Model, Preserve]
[BaseType(typeof(ICISMPDeviceDelegate))]
public interface ICBarCodeReaderDelegate
{
// @required -(void)barcodeData:(id)data ofType:(int)type;
[Abstract]
[Export("barcodeData:ofType:")]
[EventArgs("BarcodeData")]
void BarcodeData(string data, BarCodeSymbologies type);
// @required -(void)configurationRequest;
[Abstract]
[Export("configurationRequest")]
void ConfigurationRequest();
}
Это позволяет вам в вашем проекте:
public void Init()
{
_sharedBarCodeReader.BarcodeData += OnBarcodeData;
}
private void OnBarcodeData(object sender, BarcodeDataEventArgs e)
{
var barcode = Convert.ToString(sender); // this maps to string data
//BarCodeSymbologies is in BarcodeDataEventArgs
var handler = BarCodeData;
if (handler != null)
handler(this, barcode);
}
Однако этот подход терпит неудачу, когда метод не имеет параметров, как сказано в сообщении об ошибке btouch.
Другой подход, который я только обнаружил (и теперь кажется прямым и простым), заключается не в том, чтобы делегировать делегата как события, например
// @interface ICBarCodeReader : ICISMPDevice
[DisableDefaultCtor]
[BaseType(typeof(ICISMPDevice))]
public interface ICBarCodeReader
{
[Wrap("WeakDelegate")]
ICBarCodeReaderDelegate Delegate { get; set; }
// @property (assign, nonatomic) id<ICISMPDeviceDelegate,ICBarCodeReaderDelegate> delegate;
[NullAllowed, Export("delegate", ArgumentSemantic.Assign)]
ICBarCodeReaderDelegate WeakDelegate { get; set; }
}
И вместо этого создайте реализацию интерфейса делегата.
например
public void Init()
{
_sharedBarCodeReader.Delegate = new BarCodeReaderDelegate(this);
}
private class BarCodeReaderDelegate : ICBarCodeReaderDelegate
{
public BarCodeReaderDelegate(BarCodeScanner barCodeScanner)
{
_barCodeScanner = barCodeScanner;
}
public override void BarcodeData(string data, BarCodeSymbologies type)
{
var handler = _barCodeScanner.BarCodeData;
if (handler != null)
handler(this, data);
}
public override void ConfigurationRequest() { }
private readonly BarCodeScanner _barCodeScanner;
}
Надеюсь, это поможет кому-то другому.
"CaptureComplete:" Может ли ожидать отправителя?
registrar found a signature mismatch in the method
ошибкеregistrar found a signature mismatch in the method
дальнейшем.:
в[Export()]
и теперь он компилируется.