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);
}
我正在使用一个遗留库,它允许我调用 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);
}