129

AppleはCarbon64ビット対応を作成していないため、C++とCocoaフレームワークを使用するアプリケーションを作成したいと思います。C ++は、LinuxとWindowsでの実装ではかなりバニラのようですが、Mac OS Xでは、追加のApple固有のコードが必要なようです(Obj-Cラッパーなど)。また、私が間違っているかもしれないが、Appleは開発者にC++ではなくObjective-Cで書くことを強制しているようだ。

クロスプラットフォームを維持しやすいMacでコードを書くための道を見つけようとしています。Linux /Windows用のC++でコードを記述してから、Objective-Cで大部分を書き直さなければならないのは、非常に非効率的です。

将来的にサポートされ、XcodeでサポートされるC ++でコードを書く方法はありますか?また、これが可能な場合、XcodeでC ++とObjective-Cをどのように組み合わせるのですか?ありがとう。

4

7 に答える 7

115

Cocoa アプリケーション全体を C++ で作成することはできません。Cocoa は、キーと値のバインディング、デリゲート (Cocoa スタイル)、ターゲット アクション パターンなどのコア テクノロジの多くについて、Objective-C のレイト バインディング機能に大きく依存しています。遅延バインディング要件により、C++ⁱ のようなコンパイル時にバインドされた型付き言語で Cocoa API を実装することは非常に困難になります。もちろん、OS X で実行される純粋な C++ アプリを作成することもできます。ただし、Cocoa API を使用することはできません。

したがって、他のプラットフォームの C++ アプリと Cocoa ベースのアプリケーションの間でコードを共有する場合は、2 つのオプションがあります。1 つ目は、モデル層を C++ で記述し、GUI を Cocoa で記述することです。これは、 Mathematicaなどの一部の非常に大規模なアプリで使用される一般的なアプローチです。C++ コードは変更せずにそのままにしておくことができます (OS X で C++ を作成またはコンパイルするために、「ファンキーな」Apple 拡張機能は必要ありません)。あなたのコントローラーレイヤーはおそらくObjective-C++を利用するでしょう(おそらくあなたが言及している「ファンキーな」Apple拡張機能)。Objective-C++ は、Objective-C が C のスーパーセットであるように、C++ のスーパーセットです。Objective- [some-objc-object callMethod];C++ では、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 にすることができます。

2 番目のオプションは、クロスプラットフォームの C++ ツールキットを使用することです。Qt _ツールキットは法案に合うかもしれません。クロスプラットフォーム ツールキットは一般的に Mac ユーザーに軽蔑されます。なぜなら、彼らはすべてのルック アンド フィールの詳細を正確に把握できず、Mac ユーザーは Mac アプリケーションの UI に洗練されたものを期待するからです。ただし、Qt は驚くほど優れた機能を発揮します。対象ユーザーやアプリの使用状況によっては、Qt で十分な場合もあります。さらに、コア アニメーションや一部の QuickTime 機能など、OS X 固有のテクノロジの一部を利用できなくなりますが、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 で利用できるようにしましたが、ブリッジには大規模な手動調整が必要であり、上記のキーと値のバインドなどのより高度なテクノロジを処理できませんでした。現在、Python、Ruby などの動的に型付けされ、ランタイムにバインドされた言語は、Objective-C を使用せずに Cocoa アプリを作成するための唯一の現実的なオプションです (もちろん、これらのブリッジは内部で Objective-C を使用しています)。

于 2009-02-09T17:11:00.453 に答える
70

ばかげているように聞こえるかもしれませんが、実際には純粋な 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;
}
于 2012-12-29T15:40:31.503 に答える
18

はい、C ++を使用する(つまり、*。cppファイルに書き込む)だけでなく、*。mmファイル内でC ++とObjective-Cを混在させることもできます(標準のObjective-Cコードは* .mファイルに保存されます)。

もちろん、ユーザーインターフェイスにはObjective-Cを使用し、C++オブジェクトにはObjective-Cラッパーを作成する必要があります。もう1つのオプションは、Windows、Mac OS X、およびLinuxをサポートするC ++フレームワークであるQtに切り替えることです。これは、次のバージョン4.5でLGPLの下でリリースされる予定です。

于 2009-02-08T12:31:47.327 に答える
9

はい、それらを混在させることができます。

GUI オブジェクトを直接操作し、それらから通知を受け取るには、Objective-C を使用する必要があります。

これらの Objective-C オブジェクトは、純粋な Objective-C .m ファイルではなく .mm ファイルに配置すると、C++ ロジックを直接呼び出すことができます。Objective-C++ を示すために大文字の .M を使用することを提案する (かなり) 古いアドバイスが表示される場合がありますが、これは非常に不安定であり、コンパイラと同様に混乱する可能性があります。

すべての C++ オブジェクトをラップする必要はありませんが、Objective-C コードにはそれらへのポインターを含める必要があります。

Apple は、これを行う方法を示すサンプルを公開しなくなりました。

Realm [Objective] C++: What Could Possibly Go Wrong?でホストされている Peter Steinberger による素晴らしいビデオがあります。Objective-C++ をまだ使用している人には強くお勧めします。トランスクリプトをすばやく読むことができます。

于 2009-02-08T13:37:30.753 に答える
4

単純なバニラ C++ を使用したいだけの場合、これは完全にサポートされており、他のプラットフォームとまったく違いはありません。Xcode には、[ファイル] > [新しいプロジェクト] > [コマンド ライン ユーティリティ] > [C++ ツール] の下にテンプレートもあります。また、多くの一般的なオープンソース ライブラリ (libcurl、libxml2、sqlite など) が OS X に付属しており、動的リンクに使用できます。必要がなければ、Cocoa や Apple 固有のものを使用する必要はありません。

アプリの特定の部分で Cocoa を使用したい場合は、Objective-C++をご覧ください。C++ と Objective-C を同じファイルに混在させるには、拡張子 .mm を付けるか、Xcode でファイルを右クリックして [情報を見る] > [全般] を選択し、[ファイルの種類] を sourcecode.cpp.objcpp に変更します。2 番目のオプションは、Mac 固有の #ifdef 内で Objective-C を使用する .cpp ファイルがある場合に便利です。

于 2009-02-08T18:24:57.363 に答える
2

これは何年も前の質問ですが...

いくつかの Cocoa クラスの C++ ラッパーを作成しようとしました。

とてもいい経験でした。C++ は、Objective-C よりも優れた型安全性を提供し、より少ないコードを記述できるようにしました。ただし、コンパイル時間とメモリの安全性は低下します。可能ですが、一部の動的ベースの機能は扱いが簡単ではありませんでした。C++で扱うのは意味がないと思います。

とにかく、Swift の発表により、私のプロジェクトは最終的に放棄されました。最初に C++ を使用したかったすべての理由をクリアし、さらに優れた機能を提供します。

于 2014-11-02T17:59:11.610 に答える
0

純粋にグラフィカルなアプリケーションを作成している場合、つまりコードを使用してすべてを描画している場合は、openFrameworksを検討してください。これは、C/C++ の上に構築されたオープンソースのグラフィカル プログラミング言語です。人々が言語を拡張できるようにするアドオンがあります。彼らはiphone用のアドオンを持っています。iPhone および iPod touch 用のアプリをコンパイルするのに役立つライブラリと XCode プロジェクトが付属していると思います。

于 2010-03-01T04:37:04.217 に答える