Jump to content
#ifdef

XE5 > RIO

Recommended Posts

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

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

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

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
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
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

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 by Dave Nottage
  • Like 1

Share this post


Link to post

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.

  • Like 1

Share this post


Link to post

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 ...

  • Like 1

Share this post


Link to post

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 by Christen Blom-Dahl

Share this post


Link to post

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 by Christen Blom-Dahl

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×