当前位置:  开发笔记 > 编程语言 > 正文

将C++与Cocoa一起使用而不是Objective-C?

如何解决《将C++与Cocoa一起使用而不是Objective-C?》经验,为你挑选了4个好方法。

我想编写使用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?谢谢.



1> Barry Wark..:

你不能完全用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

您可以在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).



2> 小智..:

嗯,这可能听起来很愚蠢,但实际上我们可以编写纯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 
#include 
#include 
#include 

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;
}


这很棒.是否有更复杂的例子?例如,开设NSWindow?
@Jichao看到Clang与[内部Objective-C类型]的兼容性(http://clang.llvm.org/compatibility.html#objc_objs-cast) - 修复很简单:将`objc_getClass`替换为`(id)objc_getClass`

3> fhe..:

是的,你可以只使用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.


请注意,如果您使用Qt,您的应用程序将会很糟糕.基于Qt的应用程序看起来并不像本机Mac应用程序.(例如,请参阅Google地球.)
彼得:那根本不是真的.基于Qt的应用程序外观和感觉与原生Mac应用程序完全相同,您只需要进行每个平台的调整,这比在每个平台上编写本机GUI要容易得多.
他们确实使用原生控件,这就是Qt拥有Cocoa和Carbon版本的原因.它有其他问题,但很多人在Mac上运送Qt应用程序,它们工作正常(完全有点调整).
迈克,你被误导了.在他们的其他缺点中,Mac上的基于Qt的应用程序根本不使用本机控件,而Qt库本身就完成了所有的绘图.这意味着Qt应用程序无法获得2D渲染的任何硬件加速,它们不会与Apple对标准控件进行的UI更改保持同步,并且Qt应用程序无法提供ADA合规性或脚本性,除非您重新发明这些自己开车.换句话说,请勿尝试在Mac上发布Qt应用程序.谷歌可以逃脱它:你做不到.
仅使用本机控件并不意味着它看起来和**感觉像本机应用程序一样.什么使本机感觉是每个操作系统的*差异*.如果您调整应用程序以在特定平台中感受到,则在其他平台上不会感觉到原生.并且,在一次抽象层上微调小行为总是比在本机层上进行微调更难.

4> Andy Dent..:

是的你可以混合它们.

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

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

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

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

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

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有