iOS 如何从 C 函数调用静态 Objective-C 方法?

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

我正在使用一个遗留库,它允许我调用 C 函数来响应某些事件。

我无法将参数传递给 C 函数。我希望 C 函数将事件引发到 Objective-C 代码。

我找不到一个清楚的例子,我看到的例子是通过 id 将参数传递给 C 函数。我的代码无法传入参数(库会调用C函数)

如何从 C 函数中调用 Objective-C static/class 方法?

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

根据 this Whosebug answer,您可以将 Objective-C 对象传递给 C 方法。尽管该答案专门涉及传递 class 的实例并调用实例方法而不是静态方法,但请按照我的想法尝试一下,除非我错过了一些明显的东西,否则它应该可以工作。

我知道你说过这不理想,因为你的库会调用 C 函数,但也许有另一种方法来传递它?

像这样用 id 参数定义 C 方法:

void cFunction(id param)

然后称它(某物)为:

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

按照此修改上面的代码

//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];
}

如果不能接受

您可以根据 This Whosebug post 在 Core Foundation 中利用 NSNotificationCenter,但如果您需要 [ActionNotifier printMessage] 是静态的,则需要执行 [NSNotificationCenter addObserver] 连线-在其他地方。

//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);
}