#ifdef 12 Posted December 9, 2019 Hi everyone! Need your help with old one sample* from Christen Blom-Dahl: objc_msgSend((FStillImageOutput as ILocalObject).GetObjectID, sel_getUid('addObserver:forKeyPath:options:context:'), FVideoCaptureDelegate.GetObjectID, (NSSTR('capturingStillImage') as ILocalObject).GetObjectID, NSKeyValueObservingOptionNew, (FAVCaptureStillImageIsCapturingStillImageContext as ILocalObject).GetObjectID); * article + listing I have an error message "Too many actual parameters", of course. And don't know what should I do now in Delphi 10.3.3. Found a similar question but it is unanswered too. Any suggestions? Share this post Link to post
David Heffernan 2345 Posted December 9, 2019 The error message tells you that you are supplying more arguments to a function call than expected. Look at the declaration of the function in question. Look at the list of parameters. Look at the arguments you pass. Where is the mismatch? Share this post Link to post
#ifdef 12 Posted December 9, 2019 Ok, I'll try in other words: how to split (or merge) correctly that too big objc-message for success send? I see where mismatch is (the Macapi.ObjCRuntime is not so far) but don't understand what should I do with it. Share this post Link to post
Gustav Schubert 25 Posted December 9, 2019 I am looking at Macapi.ObjCRuntime. There is a function objc_msgSendP2. What if you declare objc_msgSendP4? There are 5 calls to objc-msgSend in the uFMain unit. Three take two params, these do compile? One takes 4 Params, should be objc_msgSendP2? One takes 6 params, which should be objc_msgSendP4? Share this post Link to post
#ifdef 12 Posted December 10, 2019 15 hours ago, Gustav Schubert said: I am looking at Macapi.ObjCRuntime. There is a function objc_msgSendP2. What if you declare objc_msgSendP4? There are 5 calls to objc-msgSend in the uFMain unit. Three take two params, these do compile? One takes 4 Params, should be objc_msgSendP2? One takes 6 params, which should be objc_msgSendP4? Thanks a lot for suggestion! I'll see which variant is right the best for me :) Share this post Link to post
#ifdef 12 Posted December 10, 2019 (edited) I think Christen Blom-Dahl is in da house but not sure Edited December 10, 2019 by #ifdef Share this post Link to post
Gustav Schubert 25 Posted December 10, 2019 const libImageIO = '/System/Library/Frameworks/ImageIO.framework/ImageIO'; function objc_msgSendP4( theReceiver: Pointer; theSelector: Pointer; P1: Pointer; P2: Pointer; P3: LongWord; // ? P4: Pointer): Pointer; cdecl; overload; external libobjc name _PU + 'objc_msgSend'; You could find out if it is a long word or an Integer and if it works ... Share this post Link to post
Dave Nottage 557 Posted December 10, 2019 (edited) If FStillImageOutput is a AVCaptureStillImageOutput, you could do this: AVCaptureStillImageOutput = interface(iOSapi.AVFoundation.AVCaptureStillImageOutput) ['{A1669519-9901-489E-BDD1-A0E697C8C6CB}'] procedure addObserver(observer: NSObject; forKeyPath: NSString; options: NSKeyValueObservingOptions; context: Pointer); cdecl; end; TAVCaptureStillImageOutput = class(TOCGenericImport<AVCaptureStillImageOutputClass, AVCaptureStillImageOutput>) end; ... TAVCaptureStillImageOutput.Wrap(FStillImageOutput).addObserver(FVideoCaptureDelegate, NSObjectToID(StrToNSStr('capturingStillImage')), NSKeyValueObservingOptionNew, NSObjectToID(FAVCaptureStillImageIsCapturingStillImageContext)); NSObjectToID comes from Macapi.Helpers Edited December 10, 2019 by Dave Nottage 1 Share this post Link to post
Gustav Schubert 25 Posted December 11, 2019 Yes, this compiles - with small changes - and looks much better. AVCaptureStillImageOutput = interface(iOSapi.AVFoundation.AVCaptureStillImageOutput) ['{A1669519-9901-489E-BDD1-A0E697C8C6CB}'] procedure addObserver(observer: Pointer; forKeyPath: NSString; options: NSKeyValueObservingOptions; context: Pointer); cdecl; procedure captureStillImageAsynchronouslyFromConnection(connection: AVCaptureConnection; completionHandler: TAVCaptureCompletionHandler); cdecl; end; TAVCaptureStillImageOutput = class(TOCGenericImport<AVCaptureStillImageOutputClass, AVCaptureStillImageOutput>) end; // objc_msgSendP4((FStillImageOutput as ILocalObject).GetObjectID, // sel_getUid('addObserver:forKeyPath:options:context:'), // FVideoCaptureDelegate.GetObjectID, // (StrToNSStr('capturingStillImage') as ILocalObject).GetObjectID, // NSKeyValueObservingOptionNew, // (FAVCaptureStillImageIsCapturingStillImageContext as ILocalObject).GetObjectID); TAVCaptureStillImageOutput.Wrap(FStillImageOutput).addObserver( FVideoCaptureDelegate.GetObjectID, StrToNSStr('capturingStillImage'), NSKeyValueObservingOptionNew, NSObjectToID(FAVCaptureStillImageIsCapturingStillImageContext)); { [stillImageOutput addObserver:self forKeyPath:@"capturingStillImage" options:NSKeyValueObservingOptionNew context:AVCaptureStillImageIsCapturingStillImageContext]; } Source Link. 1 Share this post Link to post
Dave Nottage 557 Posted December 11, 2019 Thanks for the changes.. but does it work? 😉 Share this post Link to post
Gustav Schubert 25 Posted December 11, 2019 I don't know if it works, I am just learning - how to code against the api, I only compile and read some interesting code. It is for the original poster to test it out, waiting ... 1 Share this post Link to post
Christen Blom-Dahl 7 Posted March 16, 2020 (edited) Sorry for my late answer (I've been very busy for some months). This code was compiled against Delphi XE5 and the iOS RTL has changed a lot since then. Nonetheless the code is a good sample that should run with minor adjustments. Regards Edited March 16, 2020 by Christen Blom-Dahl Share this post Link to post
Christen Blom-Dahl 7 Posted March 16, 2020 (edited) With newer versions of Delphi you should define the function: function objc_msgSendP4(theReceiver: Pointer; theSelector: Pointer; P1,P2,P3,P4: Pointer): Pointer; cdecl; overload; external libobjc name _PU + 'objc_msgSend'; And then you can use it as follows: objc_msgSendP4((FStillImageOutput as ILocalObject).GetObjectID, sel_getUid('addObserver:forKeyPath:options:context:'), FVideoCaptureDelegate.GetObjectID, (StrToNSStr('capturingStillImage') as ILocalObject).GetObjectID, Pointer(NSKeyValueObservingOptionNew), (FAVCaptureStillImageIsCapturingStillImageContext as ILocalObject).GetObjectID); Nonetheless, the best solution is the one posted by Gustav some posts ago. objc_msgSend should be avoided if possible. Regards Edited March 16, 2020 by Christen Blom-Dahl Share this post Link to post