我不确定这是否可能,但是在纯C代码中,是否可以调用Cocoa API?
类似于#include <cocoa.h>
,添加相应的库并进行操作吗?
感谢帮助。
objc_msgSend
, objc_getClass
等)。void cFunction() {
[[NSString alloc] init];
}
在一个 .c 文件内
void cFunction() {
void* cls = objc_getClass("NSString");
void* obj = objc_msgSend(cls, NSSelectorFromString(CFSTR("alloc")));
obj = objc_msgSend(obj, NSSelectorFromString(CFSTR("init")));
}
如果您选择第二种方法,请参见Objective-C Runtime参考文档。Objective-C是在C语言之上的一个非常薄的封装。编译器只是将代码翻译成C语言。
[obj message:argument];
转化为 C 调用
obj_msgSend(obj,@selector(message:),argument);
这就是全部内容(其中 @selector(message:)
是一种魔术编码,将选择器(方法名)转换为计算机可理解的东西)。
因此,从编译器的角度来看,Objective-C 和 C 之间没有太大的区别。例如,您可以使用 Objective-C 编译器编译纯 C 程序,得到与使用 C 编译器编译相同的结果。
因此,“混合”一些 Objective-C 和 C 的最简单方法是使用 .m
扩展名,这样编译器就会使用 Objective-C。
这不会使您的程序突然变得非常 Objective-C 风格。您可以保持几乎纯 C 的程序,只需使用扩展名 .m
即可轻松添加一些 Objective-C 消息调用。
objc_msgSend
是错误的做法。你应该将其转换为适当的函数类型:typedef CFStringRef (*StringWithStringIMP)(id, SEL, CFStringRef); CFStringRef string = ((StringWithStringIMP)objc_msgSend)(objc_getClass("NSString"), sel_getUid("foo"), CFSTR("This is pointless."));
- Jens Ayton#include
吗?我希望继续只有普通的C文件和一个Makefile来编译和链接它(不依赖于XCode来完成)。 - Mr Aleph-Xlinker -framework -Xlinker Foundation
来实现。你应该使用#include <Foundation/NSObjcRuntime.h>
来获取当前运行时头文件。 - ughoavgfhw.c
文件中使用objc_msgSend
。只需使用.m
文件即可。您可以通过使用gcc foo.m -o foo.o -framework Foundation -framework Cocoa
等方式,在没有 XCode 的情况下编译.m
文件。 - Yuji