与 Cocoa 一起使用 C + + 代替 Objective-C? ?

我想编写使用 C + + 和 Cocoa 框架的应用程序,因为苹果公司并没有制造具有 Carbon 64位功能的应用程序。C + + 在 Linux 和 Windows 上的实现似乎相当普通,但在 Mac OS X 上似乎需要额外的苹果特定代码(比如 Obj-C 包装器)。苹果似乎也在强迫开发人员使用 Objective-C 而不是 C + + 编写代码,尽管我可能错了。

我正试图找到一种在 Mac 上编写代码的方法,这种方法可以很容易地保持跨平台。必须用 C + + 为 Linux/Windows 编写代码,然后在 Objective-C 中重写大部分代码,这将是非常低效的。

有没有一种用 c + + 编写代码的方法能够在未来得到支持并且在 Xcode 得到支持?另外,如果可能的话,我该如何在 Xcode 混合使用 c + + 和 Objective-C?谢谢。

88573 次浏览

是的,你可以直接使用 C + + (也就是用 * 写入)。Cpp 文件) ,甚至在 * 中混合使用 C + + 和 Objective-C。Mm 文件(标准 Objective-C 代码存储在 * 。文件)。

当然,您仍然必须为您的用户界面使用 Objective-C,并为您的 C + + 对象创建 Objective-C 包装器。另一个选择是切换到 QT,它是一个支持 Windows、 Mac OS X 和 Linux 的 C + + 框架,将在下一个4.5版本的 LGPL 下发布。

是的,你可以混合它们。

您需要使用 Objective-C 直接操作 GUI 对象并接收来自它们的通知。

这些 Objective-C 对象可以直接调用 C + + 逻辑,如果你把它们放进去的话。Mm 文件,而不是纯 Objective-C。M 档案。注意,您可能会看到(更早的)建议使用大写字母的建议。M 表示 Objective-C + + ,但这非常奇怪,可能会使您和编译器都感到困惑。

您不需要包装每一个 C + + 对象,但是您的 Objective-C 代码需要包含指向它们的指针。

苹果公司不再发布任何示范如何做到这一点。

有一个伟大的视频由 Peter Steinberger 主持在王国 [目标] C + + : 什么可能会出错?我强烈推荐给任何人仍然使用 Objective-C + + ,你可以快速浏览文本。

如果您只是想使用普通的 C + + ,那么它绝对受到支持,并且与其他平台没有什么不同。Xcode 甚至在 File > New Project > Command Line Utility> C + + Tool 下面有一个模板。此外,许多流行的开源库(libcurl、 libxml2、 sqlite 等)都带有 OS X,可用于动态链接。如果你不想,你不必使用 Cocoa 或者任何苹果特有的东西。

如果你确实想在应用程序的某些部分使用 Cocoa,看看 目标-C + + 。您可以在同一个文件中混合使用 C + + 和 Objective-C,方法是给它一个扩展名。Mm,或者右键单击 Xcode 的文件,选择 Get Info > General,然后将文件类型更改为 sourcecode.cpp.objeccpp。如果有一个。Cpp 文件,其中您希望在 Mac 特定的 # ifdef 中使用 Objective-C。

您不能完全用 C + + 编写 Cocoa 应用程序。对于其许多核心技术,如键值绑定、委托(Cocoa 风格)和目标操作模式,Cocoa 严重依赖 Objective-C 的后期绑定功能。后期绑定要求使得 非常难以在编译时绑定的类型化语言(如 C + + i)中实现 Cocoa API。当然,您可以编写一个运行在 OS X 上的纯 C + + 应用程序。它只是不能使用 Cocoa API。

因此,如果希望在其他平台上的 C + + 应用程序和基于 Cocoa 的应用程序之间共享代码,有两种选择。第一种是用 C + + 编写模型层,用 Cocoa 编写 GUI。这是一些非常大的应用程序常用的方法,包括 Mathematica。您的 C + + 代码可以保持不变(在 OS X 上编写或编译 C + + 不需要“ funky”Apple 扩展)。您的控制器层可能会使用 Objective-C + + (可能是您提到的“时髦的”Apple 扩展)。Objective-C + + 是 C + + 的超集,就像 Objective-C 是 C 的超集一样。在 Objective-C + + 中,您可以在 C + + 函数中进行 objecc 风格的消息传递调用(如 [some-objc-object callMethod];)。相反,您可以在 ObjecC 代码中调用 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

您可以在 Objective-C 语言 向导中找到更多关于 Objective-C + + 的信息,然后视图层可以是纯 Objective-C 的。

第二种选择是使用跨平台的 C + + 工具包。QT工具包可能符合要求。跨平台工具包通常被 Mac 用户鄙视,因为它们不能准确地获得所有的外观和感觉细节,而且 Mac 用户希望 Mac 应用程序的 UI 更加完美。然而,Qt 做得出人意料的好,取决于用户和应用程序的使用情况,它可能已经足够好了。此外,您将失去一些特定于 OS X 的技术,如 Core Animation 和一些 QuickTime 功能,尽管在 Qt API 中有一些近似的替代品。正如你指出的,碳不会被移植到64位。由于 Qt 是在 Carbon API 上实现的,Trolltech/Nokia 必须将 Qt 移植到 Cocoa API,以使其具有64位兼容性。我的理解是,Qt 的下一个版本(目前在 释放候选人中)完成了这个转换,并且在 OS X 上是64位兼容的。如果您对集成 C + + 和 Cocoa API 感兴趣,那么您可能需要查看 Qt 4.5的源代码。


有一段时间,苹果公司让 Java 可以使用 Cocoa API,但是这个桥梁需要大量的手工调整,并且无法处理更先进的技术,比如上面描述的键值绑定。当前动态类型的、运行时绑定的语言,如 Python、 Ruby 等,是编写不使用 Objective-C 的 Cocoa 应用程序的唯一真正选择(当然,这些桥梁在底层使用 Objective-C)。

如果您正在编写一个纯粹的图形化应用程序,例如,您正在使用代码绘制所有内容,请考虑 OpenFramework。它是一种构建在 C/C + + 之上的开源图形编程语言。它有 插件,允许人们扩展语言。他们有 Iphone 的插件。我相信这个程序库和 XCode 项目会帮助你为 iPhone 和 iPod touch 编译应用程序。

这听起来可能有点傻,但实际上我们可以编写纯 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;
}

虽然这是个老问题了。

我有 尝试为一些 Cocoa 类编写 C + + 包装器

这是非常好的经历。C + + 提供了比 Objective-C 更好的类型安全性,并使我编写的代码更少。但是编译时间和内存安全性更差。这是可能的,但是一些基于动态的特性并不容易处理。我认为在 C + + 中处理这个问题没有意义。

不管怎样,我的项目最终被放弃,由于斯威夫特的公告。它首先澄清了我想使用 C + + 的所有理由,并且提供了更多更好的内容。