在 Cocoa 中使用 C++ 而不是 Objective-C?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/525609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:47:40  来源:igfitidea点击:

Use C++ with Cocoa Instead of Objective-C?

c++objective-ccocoalanguage-interoperability

提问by Brock Woolf

I would like to write applications that use C++ and the Cocoa frameworks because Apple is not making Carbon 64-bit capable. C++ seems to be pretty vanilla in its implementation on Linux and Windows but on Mac OS X it seems like additional Apple specific pieces of code are required (like an Obj-C wrapper). It also seems that Apple is forcing developers to write in Objective-C rather than C++, although I could be wrong.

我想编写使用 C++ 和 Cocoa 框架的应用程序,因为 Apple 不支持 Carbon 64 位。C++ 在 Linux 和 Windows 上的实现似乎很普通,但在 Mac OS X 上,似乎需要额外的 Apple 特定代码(如 Obj-C 包装器)。Apple 似乎也在强迫开发人员使用 Objective-C 而不是 C++ 来编写代码,尽管我可能是错的。

I am trying to find a path to write code on the Mac that would be easy to keep cross platform. Having to write code in C++ for Linux/Windows and then rewrite large portions in Objective-C would be very inefficient.

我正在尝试找到一种在 Mac 上编写代码的路径,以便于保持跨平台。必须用 C++ 为 Linux/Windows 编写代码,然后在 Objective-C 中重写大部分代码会非常低效。

Is there a way to write code in C++ that will be supported for the future and supported in Xcode? Also, if this is possible, how would I mix C++ and Objective-C in Xcode? Thanks.

有没有办法用 C++ 编写代码,以便将来支持并在 Xcode 中支持?另外,如果这是可能的,我将如何在 Xcode 中混合使用 C++ 和 Objective-C?谢谢。

采纳答案by Barry Wark

You cannot write a Cocoa application entirely in C++. Cocoa relies heavily on the late binding capabilities of Objective-C for many of its core technologies such as Key-Value Bindings, delegates (Cocoa style), and the target-action pattern. The late binding requirements make it verydifficult to implement the Cocoa API in a compile-time bound, typed language like C++?. You can, of course, write a pure C++ app that runs on OS X. It just can't use the Cocoa APIs.

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

So, you have two options if you want to share code between C++ apps on other platforms and your Cocoa-based application. The first is to write the model layer in C++ and the GUI in Cocoa. This is a common approach used by some very large apps, including Mathematica. Your C++ code can be left unchanged (you do not need "funky" apple extensions to write or compile C++ on OS X). Your controller layer will likely make use of Objective-C++ (perhaps the "funky" Apple extension you refer to). Objective-C++ is a superset of C++, just as Objective-C is a superset of C. In Objective-C++, you can make objc-style message passing calls (like [some-objc-object callMethod];) from within a C++ function. Conversely, you can call C++ functions from within ObjC code like:

因此,如果您想在其他平台上的 C++ 应用程序和基于 Cocoa 的应用程序之间共享代码,您有两种选择。首先是用C++写模型层,用Cocoa写GUI。这是一些非常大的应用程序使用的常用方法,包括Mathematica。您的 C++ 代码可以保持不变(您不需要“时髦的”苹果扩展来在 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

You can find out more about Objective-C++ in the Objective-C language guide. The view layer can then be pure Objective-C.

您可以在 Objective-C 语言指南 中找到有关 Objective-C++ 的更多信息。视图层可以是纯Objective-C。

The second option is to use a cross-platform C++ toolkit. The Qttoolkit might fit the bill. Cross-platform toolkits are generally despised by Mac users because they do not get all the look and feel details exactly right and Mac users expect polish in the UI of Mac applications. Qt does a surprisingly good job, however, and depending on the audience and the use of your app, it may be good enough. In addition, you will lose out on some of the OS X-specific technologies such as Core Animation and some QuickTime functionality, though there are approximate replacements in the Qt API. As you point out, Carbon will not be ported to 64-bit. Since Qt is implemented on Carbon APIs, Trolltech/Nokia have had to port Qt to the Cocoa API to make it 64-bit compatible. My understanding is that the next relase of Qt (currently in release candiate) completes this transition and is 64-bit compatible on OS X. You may want to have a look at the source of Qt 4.5 if you're interested in integrating C++ and the Cocoa APIs.

第二种选择是使用跨平台的 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 的源代码。



? For a while Apple made the Cocoa API available to Java, but the bridge required extensive hand-tuning and was unable to handle the more advanced technologies such as Key-Value Bindings described above. Currently dynamically typed, runtime-bound languages like Python, Ruby, etc. are the only real option for writing a Cocoa app without Objective-C (though of course these bridges use Objective-C under the hood).

? 有一段时间,Apple 将 Cocoa API 提供给 Java,但该桥需要大量的手动调整,并且无法处理更先进的技术,例如上述的键值绑定。目前动态类型的、运行时绑定的语言,如 Python、Ruby 等,是编写没有 Objective-C 的 Cocoa 应用程序的唯一真正选择(当然,这些桥接器在底层使用了 Objective-C)。

回答by FX. J. Adi Lima

Well, it may sound silly, but actually we can write pure C++ code to create GUI for Mac OS X, but we must link against Cocoa framework.

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

回答by fhe

Yes, you can just use C++ (i.e. writing it in *.cpp files) and even mix C++ and Objective-C inside *.mm files (standard Objective-C code is stored in *.m files).

是的,您可以只使用 C++(即在 *.cpp 文件中编写它),甚至可以在 *.mm 文件中混合 C++ 和 Objective-C(标准 Objective-C 代码存储在 *.m 文件中)。

Of course, you still have to use Objective-C for your user-interface and create Objective-C wrappers for your C++ objects. Another option is to switch to Qtwhich is a C++ Framework that supports Windows, Mac OS X, and Linux -- and will be released under the LGPL with the next version 4.5.

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

回答by Andy Dent

Yes you can mix them.

是的,你可以混合它们。

You need to use Objective-C to directly operate on your GUI objects and receive notifications from them.

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

These Objective-C objects can directly call C++ logic if you put them in .mm files, instead of the pure Objective-C .m files. Note that you may see (much) older advice suggesting using an uppercase .M to indicate Objective-C++ but this is very flaky and likely to confuse you as well as the compiler.

如果将这些 Objective-C 对象放在 .mm 文件中,而不是纯粹的 Objective-C .m 文件,则它们可以直接调用 C++ 逻辑。请注意,您可能会看到(很多)较旧的建议,建议使用大写的 .M 来表示 Objective-C++,但这非常不稳定,可能会使您和编译器感到困惑。

You don't need to wrap each and every C++ object but your Objective-C code will need to contain pointers to them.

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

Apple no longer publish any samples showing how to do this.

Apple 不再发布任何展示如何执行此操作的示例。

There's a great video by Peter Steinberger hosted at Realm [Objective] C++: What Could Possibly Go Wrong?I highly recommend for anyone still using Objective-C++ and you can quickly skim the transcript.

在 Realm [Objective] C++ 上,Peter Steinberger 提供了一段很棒的视频:什么可能出错?我强烈推荐任何仍在使用 Objective-C++ 的人,你可以快速浏览成绩单。

回答by Matt Stevens

If you're just looking to use plain vanilla C++, this is absolutely supported and really no different than any other platform. Xcode even has a template for it under File > New Project > Command Line Utility > C++ Tool. Also, a number of the popular open-source libraries (libcurl, libxml2, sqlite, etc) come with OS X and are available for dynamic linking. You don't have to use Cocoa or anything Apple-specific if you don't want to.

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

If you do want to use Cocoa in certain portions of your app, take a look at Objective-C++. You can mix C++ and Objective-C in the same file by giving it an extension of .mm, or by right-clicking on the file in Xcode and selecting Get Info > General then changing the File Type to sourcecode.cpp.objcpp. The second option is useful if you have a .cpp file where you want to use Objective-C within a Mac-specific #ifdef.

如果您确实想在应用程序的某些部分使用 Cocoa,请查看Objective-C++。您可以将 C++ 和 Objective-C 混合在同一个文件中,方法是给它一个扩展名 .mm,或者在 Xcode 中右键单击文件并选择“获取信息”>“常规”,然后将“文件类型”更改为 sourcecode.cpp.objcpp。如果您有一个 .cpp 文件,您想在 Mac 特定的 #ifdef 中使用 Objective-C,则第二个选项很有用。

回答by Eonil

Though this is years old question...

虽然这是多年的问题......

I have tried to make C++ wrapper of some Cocoa classes.

试图制作一些 Cocoa 类的 C++ 包装器

It was pretty nice experience. C++ provided better type safety than Objective-C, and made me to write less code. But compile time and memory safety are worse. It is possible but some dynamic based features were not easy to handle. I think it doesn't make sense to deal with it on C++.

这是相当不错的体验。C++ 提供了比 Objective-C 更好的类型安全性,并使我编写的代码更少。但是编译时间和内存安全性更差。这是可能的,但一些基于动态的功能不容易处理。我认为在 C++ 上处理它没有意义。

Anyway my project was finally abandoned due to announcement of Swift. It cleared all the reasons I wanted to use C++ at first, and provides even more and better.

无论如何,由于 Swift 的发布,我的项目最终被放弃了。它清除了我最初想使用 C++ 的所有原因,并提供了更多更好的东西。

回答by milesmeow

If you're writing a purely graphical application, i.e. you're drawing everything using code, consider openFrameworks. It's an opensource graphical programming languages built on top of C/C++. It has addonswhich allow people to extend the language. They have an addon for the iphone. I believe that it comes with the library and the XCode projects that will help you compile apps for the iPhone and iPod touch.

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