Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
}
like image 598
Alex Stone Avatar asked May 07 '26 13:05

Alex Stone


1 Answers

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);
}
like image 110
Will Jones Avatar answered May 10 '26 04:05

Will Jones