Search code examples
ioscobjective-cpjsip

How to pass address of Objective C function to a C function?


I am working with PJSIP for SIP calling ios application. As the library is written in C some callback C methods expecting address of a Objective C function. I have tried to do

ua_cfg.cb.on_incoming_call = &[self on_incoming_call:<#(pjsua_acc_id)#> _:<#(pjsua_call_id)#> _:<#(pjsip_rx_data *)#>]

but of course it does not work as I dont know what to pass as parameters to the function, neither it's giving me the address of the function.

How can I make it work? The C function which is expecting this looks like below

void (*on_incoming_call)(pjsua_acc_id acc_id, pjsua_call_id call_id,
                 pjsip_rx_data *rdata);

Solution

  • ObjectiveC supports pure C so why not just create a C function on_incoming_call which then calls ObjectiveC code.

    I am pretty sure it is doable directly with objective C though but I wouldn't go there. The problem starts with objectiveC having extra function parameters in there that are invisible to you. For instance parameter self.

    So try something like the following:

    void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata) {
        [MyObjectiveCObject onIncomingCall...];
    }
    

    Now you can see that you may have a bit of an issue where the on_incoming_call is in static context while your object may or may not be. I usually create singletons for such cases. Most simple may look like:

    static MyReceiver *currentReceiver = nil;
    
    + (MyReceiver *)current {
        if(currentReceiver == nil) {
            currentReceiver = [[MyReceiver alloc] init];
            ua_cfg.cb.on_incoming_call = &on_incoming_call;
        }
        return currentReceiver;
    }
    

    In this case you would now call

    void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata) {
        [[MyReceiver current] onIncomingCall...];
    }