ioscobjective-cstatic-functions

iOS how to call a static Objective-C method from C function?


I'm working with a legacy library which allows me to call a C function in response to some event.

I can not pass parameters to the C function. I want the C function to raise the event to Objective-C code.

I can not find a clear example, and the examples that I see pass a parameter by id to the C function. I cannot pass in parameters in my code (the library will call the C function)

How can I call an Objective-C static/class method from C function?

//Objective-C class
@interface ActionNotifier : NSObject

+(void)printMessage;

@end

@implementation ActionNotifier

+(void)printMessage {
    NSLog(@"Received message from C code");
}

@end

//response.c source file:
#import "ActionNotifier.h"
#import <Cocoa/Cocoa.h>

void cFunction()
{
    //How can I get the equivalent of this to be called from here?
    [ActionNotifier printMessage]; //error: Expected expression
}

Solution

  • As per this StackOverflow answer, you can pass your Objective-C object to a C method. Although that answer specifically deals with passing an instance of the class and calling an instance method instead of a static one, give this a try as in my head, it should work unless I've missed something glaringly obvious.

    I know you've said this isn't ideal, as your library will call the C function, but maybe there's another way to pass this?

    Define the C method with an id parameter like this:

    void cFunction(id param)

    Then call it (something) this:

    Class thisClass = [self getClass];
    cFunction(self);
    

    Modify your above code as per this

    //Objective-C class
    @interface ActionNotifier : NSObject
    
    +(void)printMessage;
    
    @end
    
    @implementation ActionNotifier
    
    +(void)printMessage {
        NSLog(@"Received message from C code");
    }
    
    @end
    
    //C class:
    #import "ActionNotifier.h"
    #import <Cocoa/Cocoa.h>
    void cFunction(id param)
    {
        [param printSecurityMessage];
    }
    

    If that wouldn't be acceptable

    You could leverage NSNotificationCenter in Core Foundation as per This StackOverflow post, although if you need [ActionNotifier printMessage] to be static, you'll need to do the [NSNotificationCenter addObserver] wire-up somewhere else.

    //NSNotificationCenter Wire-up
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(method), @"MyNotification", nil];
    -(id)method{
        [ActionNotifier printMessage];
    }
    
    //Objective-C class
    @interface ActionNotifier : NSObject
    
    +(void)printMessage;
    
    @end
    
    @implementation ActionNotifier
    
    +(void)printMessage {
        NSLog(@"Received message from C code");
    }
    
    @end
    
    //C source: //may need to rename to .mm if you cannot see the core foundation
    #include <CoreFoundation/CoreFoundation.h>
    void cFunction()
    {
        CFNotificationCenterRef center = CFNotificationCenterGetLocalCenter();
        CFNotificationCenterPostNotification(center, CFSTR("MyNotification"), NULL, NULL, TRUE);
    }