Bro*_*olf 122 c++ cocoa objective-c language-interoperability
我想编写使用C++和Cocoa框架的应用程序,因为Apple不支持使用Carbon 64位.C++在Linux和Windows上的实现似乎相当普遍,但在Mac OS X上似乎需要额外的Apple特定代码片段(如Obj-C包装器).苹果似乎也在强迫开发人员用Objective-C而不是C++编写,尽管我可能错了.
我试图找到一条在Mac上编写代码的路径,这种代码很容易保持跨平台.必须用C++ for Linux/Windows编写代码,然后在Objective-C中重写大部分代码效率非常低.
有没有办法用C++编写代码,这些代码将来会得到支持并在Xcode中得到支持?另外,如果可以的话,我如何在Xcode中混合使用C++和Objective-C?谢谢.
Bar*_*ark 110
你不能完全用C++编写Cocoa应用程序.Cocoa很大程度上依赖于Objective-C的许多核心技术的后期绑定功能,例如Key-Value Bindings,委托(Cocoa风格)和目标 - 动作模式.后期绑定要求使得在C++中编译时绑定的类型语言中实现Cocoa API 非常困难.当然,您可以编写一个在OS X上运行的纯C++应用程序.它不能使用Cocoa API.
因此,如果要在其他平台上的C++应用程序和基于Cocoa的应用程序之间共享代码,则有两种选择.第一种是用C++编写模型层,用Cocoa编写GUI.这是一些非常大的应用程序(包括Mathematica)使用的常用方法.您的C++代码可以保持不变(您不需要"funky"apple扩展来在OS X上编写或编译C++).您的控制器层可能会使用Objective-C++(可能是您所指的"时髦"Apple扩展).Objective-C++是C++的超集,正如Objective-C是C的超集一样.在Objective-C++中,您可以[some-objc-object callMethod];
在C++函数中进行objc样式的消息传递调用(如).相反,您可以从ObjC代码中调用C++函数,如:
@interface MyClass {
MyCPPClass *cppInstance;
}
@end
@implementation MyClass
- (id)init {
if(self = [super init]) {
cppInstance = new MyCPPClass();
}
return self;
}
- (void) dealloc {
if(cppInstance != NULL) delete cppInstance;
[super dealloc];
}
- (void)callCpp {
cppInstance->SomeMethod();
}
@end
Run Code Online (Sandbox Code Playgroud)
您可以在Objective-C语言指南中找到有关Objective-C++的更多信息.然后视图层可以是纯Objective-C.
第二种选择是使用跨平台的C++工具包.在Qt的工具包可能适合该法案.跨平台工具包通常被Mac用户鄙视,因为他们没有完全正确地获得所有外观和感觉细节,并且Mac用户希望在Mac应用程序的UI中得到润色.然而,Qt做得非常出色,根据观众和应用程序的使用情况,它可能已经足够好了.此外,您将失去一些特定于OS X的技术,例如Core Animation和一些QuickTime功能,尽管Qt API中有大致替代品.正如您所指出的,Carbon不会被移植到64位.由于Qt是在Carbon API上实现的,因此Trolltech/Nokia不得不将Qt移植到Cocoa API以使其与64位兼容.我的理解是Qt的下一个关系(目前正在发布中)完成此转换并在OS X上与64位兼容.如果您对集成C++和Cocoa API感兴趣,可能需要查看Qt 4.5的源代码.
ⁱ有一段时间Apple将Cocoa API提供给Java,但是这个桥需要大量的手动调整,并且无法处理更高级的技术,例如上面描述的Key-Value Bindings.目前,动态类型化的运行时绑定语言(如Python,Ruby等)是编写没有Objective-C的Cocoa应用程序的唯一真正选择(当然这些桥梁使用了Objective-C).
小智 66
嗯,这可能听起来很愚蠢,但实际上我们可以编写纯C++代码来为Mac OS X创建GUI,但我们必须链接到Cocoa框架.
/*
* test1.cpp
* This program shows how to access Cocoa GUI from pure C/C++
* and build a truly functional GUI application (although very simple).
*
* Compile using:
* g++ -framework Cocoa -o test1 test1.cpp
*
* that will output 'test1' binary.
*/
#include <CoreFoundation/CoreFoundation.h>
#include <objc/objc.h>
#include <objc/objc-runtime.h>
#include <iostream>
extern "C" int NSRunAlertPanel(CFStringRef strTitle, CFStringRef strMsg,
CFStringRef strButton1, CFStringRef strButton2,
CFStringRef strButton3, ...);
int main(int argc, char** argv)
{
id app = NULL;
id pool = (id)objc_getClass("NSAutoreleasePool");
if (!pool)
{
std::cerr << "Unable to get NSAutoreleasePool!\nAborting\n";
return -1;
}
pool = objc_msgSend(pool, sel_registerName("alloc"));
if (!pool)
{
std::cerr << "Unable to create NSAutoreleasePool...\nAborting...\n";
return -1;
}
pool = objc_msgSend(pool, sel_registerName("init"));
app = objc_msgSend((id)objc_getClass("NSApplication"),
sel_registerName("sharedApplication"));
NSRunAlertPanel(CFSTR("Testing"),
CFSTR("This is a simple test to display NSAlertPanel."),
CFSTR("OK"), NULL, NULL);
objc_msgSend(pool, sel_registerName("release"));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
fhe*_*fhe 17
是的,你可以只使用C++(即用*.cpp文件编写),甚至在*.mm文件中混合使用C++和Objective-C(标准Objective-C代码存储在*.m文件中).
当然,您仍然必须使用Objective-C作为用户界面并为C++对象创建Objective-C包装器.另一个选择是切换到Qt,这是一个支持Windows,Mac OS X和Linux的C++ Framework - 并将在LGPL下发布,下一个版本为4.5.
是的你可以混合它们.
您需要使用Objective-C直接操作GUI对象并接收来自它们的通知.
如果将这些Objective-C对象放在.mm文件中,而不是纯粹的Objective-C .m文件,它们可以直接调用C++逻辑.请注意,您可能会看到(很多)较旧的建议,建议使用大写.M来表示Objective-C++,但这非常不稳定,可能会让您和编译器混淆.
您不需要包装每个C++对象,但您的Objective-C代码将需要包含指向它们的指针.
Apple不再发布任何显示如何执行此操作的示例.
Peter Steinberger在Realm上主持了很棒的视频[目的] C++:可能出错的是什么?我强烈推荐任何仍然使用Objective-C++的人,你可以快速浏览成绩单.