Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. iOS call object/function from Objective-C to cpp
Forum Updated to NodeBB v4.3 + New Features

iOS call object/function from Objective-C to cpp

Scheduled Pinned Locked Moved Solved Mobile and Embedded
5 Posts 2 Posters 2.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Marek
    wrote on 9 Oct 2020, 12:10 last edited by
    #1

    Hi All,

    How to call object/function from inside Objective-C *.m file ?

    On iOS I'm recording from microphone using QAudioRecorder but when call arrives, even if I discard this call, and then do stop/pause on QAudioRecorder app hangs, no error in debug, I have to kill it.
    This could be related to the fact that iOS prevents microphone use when there is a call.
    I have created a piece of code to get notified when call is comming in order to stop/pause QAudioRecorder hoping that I will be able to resume when call was ended/discarded
    So I have this notification now, how to call some function from inside Objective-C ?
    Here are my codes
    cl_objc_call.h

    #ifndef __CLObjCCall__
    #define __CLObjCCall__
    
    #include <stdio.h>
    
    class CL_ObjCCall
    {
      public:
        static int CL_objectiveC_Call(); 
    };
    #endif
    

    cl_objc_call.mm

    #include "cl_objc_call.h"
    #include "cl_objc_func.h"
    
    myCLClass* CL_obj;
    int fake;
    
    int CL_ObjCCall::CL_objectiveC_Call() {
      CL_obj=[[myCLClass alloc]init];
      [CL_obj iosCallObserver:(fake)];
      return 1;
    }
    

    cl_objc_func.h

    #ifndef __CLObjCFunc__
    #define __CLObjCFunc__
    
    #import <Foundation/Foundation.h>
    #import <CallKit/CXCallObserver.h>
    #import <CallKit/CXCall.h>
    
    @interface myCLClass:NSObject
      @property (nonatomic, strong) CXCallObserver *callObserver;
    
      -(int)iosCallObserver:(int)fake;
      -(void)iosCallObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call;
      
    @end
    #endif
    

    cl_objc_func.m

    #import "cl_objc_func.h"
    
    @implementation myCLClass 
      //Your objective c code here.... 
    -(int)iosCallObserver:(int)fake { 
          
        CXCallObserver *callObserver = [[CXCallObserver alloc] init];
        [callObserver setDelegate:self queue:nil];
        self.callObserver = callObserver;
          
        return 1;
    }
    - (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
        if(call.onHold) {
            NSLog(@"********** voice call onHold **********/n");
        }
        else if(call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false) {
            NSLog(@"********** voice call incoming **********/n");
            //here I need to call Qt to stop recorder
        }
        else if (call.hasConnected) {
            NSLog(@"********** voice call connected **********/n");
        } else if(call.hasEnded) {
            NSLog(@"********** voice call disconnected **********/n");
        }
    }
    
    @end
    

    calling Objective-C from Qt:

    CL_ObjCCall::CL_objectiveC_Call()
    

    Any Idea highly appreciated.
    Best,
    Marek

    1 Reply Last reply
    0
    • A Offline
      A Offline
      ad1170
      wrote on 9 Oct 2020, 15:00 last edited by ad1170 10 Sept 2020, 15:14
      #2

      You can call ObjC functions from cpp when you declare them as external (e.g. external void objC_function(void);) in your cpp file.
      In your .mm file you can write this function just like a normal c function. Inside this function you can access ObjC objects.

      If you want to call cpp functions from ObjC code you can do that with call back functions.
      For example:
      ObjC (.mm) file:

      void (*ptrCallBack)(int arg) = nil; // declare a pointer to the call back function
      
      // use this function to set the call back function (later called from cpp code)
      void setCallBackFunction(void (*cbFunction)(int arg))
      {
         ptrCallBack = cbFunction;
      }
      
      // write a function to call the callback function from your ObjC or Swift code
      void call_CallBack(int arg)
      {
        if(ptrCallBack != nil)
          ptrCallBack(arg);
      }
      

      However you must declare *external setCallBack(void (cbFunction(int arg)); in your cpp file.

      In your cpp code:

      
      myClass *ptrToMyClass = nullptr;  // init this pointer after the instantiation of myClass.
      
      void objC_callbackFunction(int arg)
      {
        // do something with arg
        // if you have a pointer to your cpp class, than you can call class member functions
        if(ptrToMyClass)
          ptrToMyClass->memberFunction(arg);
      }
      
      // call this in your cpp code to set the call back function
      setCallBack(&objC_callbackFunction);
      

      Note, this don't work with c++ class member functions.

      I know, this is a little bit ugly to use this workaround with call back functions. But it works when you consider a few things like nil pointer check.

      M 1 Reply Last reply 9 Oct 2020, 16:48
      0
      • A ad1170
        9 Oct 2020, 15:00

        You can call ObjC functions from cpp when you declare them as external (e.g. external void objC_function(void);) in your cpp file.
        In your .mm file you can write this function just like a normal c function. Inside this function you can access ObjC objects.

        If you want to call cpp functions from ObjC code you can do that with call back functions.
        For example:
        ObjC (.mm) file:

        void (*ptrCallBack)(int arg) = nil; // declare a pointer to the call back function
        
        // use this function to set the call back function (later called from cpp code)
        void setCallBackFunction(void (*cbFunction)(int arg))
        {
           ptrCallBack = cbFunction;
        }
        
        // write a function to call the callback function from your ObjC or Swift code
        void call_CallBack(int arg)
        {
          if(ptrCallBack != nil)
            ptrCallBack(arg);
        }
        

        However you must declare *external setCallBack(void (cbFunction(int arg)); in your cpp file.

        In your cpp code:

        
        myClass *ptrToMyClass = nullptr;  // init this pointer after the instantiation of myClass.
        
        void objC_callbackFunction(int arg)
        {
          // do something with arg
          // if you have a pointer to your cpp class, than you can call class member functions
          if(ptrToMyClass)
            ptrToMyClass->memberFunction(arg);
        }
        
        // call this in your cpp code to set the call back function
        setCallBack(&objC_callbackFunction);
        

        Note, this don't work with c++ class member functions.

        I know, this is a little bit ugly to use this workaround with call back functions. But it works when you consider a few things like nil pointer check.

        M Offline
        M Offline
        Marek
        wrote on 9 Oct 2020, 16:48 last edited by
        #3

        @ad1170 I tried to rewrite these functions to ios notation like:
        -(int)iosCallObserver:(int)fake;
        but still I would have to set callback from CL_ObjCCall something like this:
        [CL_obj setCallBack:(&objC_callbackFunction)];

        I have noticed that inside
        cl_objc_func.m
        I can access my Singleton

        else if(call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false) {
                NSLog(@"********** voice call incoming **********/n");
                //here I need to call Qt to stop recorder
                Config::get().stopRecorder()
            }
        

        And it works, just how to call some function from Singleton to my Recorder class, easiest it would be via signal but I have error: no matching function to connect to Singleton&

        In Singleton.cpp file if I define
        extern "C" void stop_recorder()
        then I can call this stop_recorder() function but it does not know about Recorder class

        Maybe its late, but more help needed ;)

        Best,
        Marek

        M 1 Reply Last reply 9 Oct 2020, 17:50
        0
        • M Marek
          9 Oct 2020, 16:48

          @ad1170 I tried to rewrite these functions to ios notation like:
          -(int)iosCallObserver:(int)fake;
          but still I would have to set callback from CL_ObjCCall something like this:
          [CL_obj setCallBack:(&objC_callbackFunction)];

          I have noticed that inside
          cl_objc_func.m
          I can access my Singleton

          else if(call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false) {
                  NSLog(@"********** voice call incoming **********/n");
                  //here I need to call Qt to stop recorder
                  Config::get().stopRecorder()
              }
          

          And it works, just how to call some function from Singleton to my Recorder class, easiest it would be via signal but I have error: no matching function to connect to Singleton&

          In Singleton.cpp file if I define
          extern "C" void stop_recorder()
          then I can call this stop_recorder() function but it does not know about Recorder class

          Maybe its late, but more help needed ;)

          Best,
          Marek

          M Offline
          M Offline
          Marek
          wrote on 9 Oct 2020, 17:50 last edited by
          #4

          OK, I think I have solved this problem, but Thanks for help.
          So for posterity:

          I have Singleton in my application and I can call functions from Singleton inside .mm file

          else if(call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false) {
                  NSLog(@"********** voice call incoming **********/n");
                  //here I need to call Qt to stop recorder
                  Config::get().stopRecorder()
              }
          

          Then in Singleton I have void pointer and two extern functions defined

           void *pointer
          extern "C" void first_function();
          extern "C" void second_function();
          

          Inside class that I need to have access to I'm initiating this pointer

          Config::get().pointer=(void*)this
          

          In Singleton cpp (which is called from .mm file, BTW I have changed cl_obj_func.m to cl_obj_func.mm without changing anything inside .m or .h file)

          void Config::stopRecorder() {
              qDebug()<<"Config::stopRecorder";
              first_function();
          }
          void first_function() {
              second_function();
          }
          

          second_function is defined in config.h (Singleton as extern) but body is in main class

          void stop_recorder2() {
              Recorder *r=(Recorder*)Config::get().recorder;
              r->stopRecorder();
          }
          

          So in short, from Singleton I call first extern function which calls second extern function from file in main class, so I have all headers included and Recorder object is known to compiler.

          Best,
          Marek

          1 Reply Last reply
          1
          • A Offline
            A Offline
            ad1170
            wrote on 10 Oct 2020, 09:27 last edited by ad1170 10 Oct 2020, 09:29
            #5

            Hi Marek,
            glad to hear that your issue is solved. I've seen, i forgot the extern "C" ... in my post, sorry.
            At the time where i have implemented this, I had found this way, but your way seems to be better.

            1 Reply Last reply
            0

            1/5

            9 Oct 2020, 12:10

            • Login

            • Login or register to search.
            1 out of 5
            • First post
              1/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved