web-dev-qa-db-ja.com

Objective-Cの代わりにCocoaでC ++を使用しますか?

AppleはCarbon 64ビットに対応していないため、C++とCocoaフレームワークを使用するアプリケーションを作成したいと思います。 Xは、追加のApple特定のコードが必要です(Obj-Cラッパーなど)。また、Appleは開発者に書き込みを強制するようですC++ではなくObjective-Cですが、間違っている可能性があります。

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

将来サポートされ、XcodeでサポートされるC++でコードを記述する方法はありますか?また、これが可能であれば、XcodeでC++とObjective-Cをどのように混在させるのですか?ありがとう。

121
Brock Woolf

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

そのため、他のプラットフォーム上のC++アプリとCocoaベースのアプリケーション間でコードを共有する場合、2つのオプションがあります。 1つ目は、モデル層をC++で、GUIをCocoaで記述することです。これは、 Mathematica など、非常に大きなアプリで使用される一般的なアプローチです。 C++コードは変更せずに残すことができます(OS XでC++を記述またはコンパイルするために「ファンキー」Apple拡張機能は必要ありません)。コントローラーレイヤーは、Objective-C++(おそらく、参照する「ファンキー」Apple拡張機能)を使用する可能性があります。 Objective-CがCのスーパーセットであるように、Objective-C++はC++のスーパーセットです。Objective-C++では、C++関数内からobjcスタイルのメッセージパッシング呼び出し([some-objc-object callMethod];など)を作成できます。逆に、次のような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++ guide を参照してください。ビューレイヤーは純粋なObjective-Cにすることができます。

2番目のオプションは、クロスプラットフォームC++ツールキットを使用することです。 Qt ツールキットは、法案に合うかもしれません。クロスプラットフォームツールキットは、すべてのルックアンドフィールの詳細が正確に得られず、MacユーザーがMacアプリケーションのUIを洗練することを期待するため、一般的にMacユーザーに軽deされています。ただし、Qtは驚くほど良い仕事をしますが、視聴者とアプリの使用状況によっては、それで十分かもしれません。さらに、Qt APIには大体の代替品がありますが、Core AnimationやQuickTime機能など、OS X固有のテクノロジーの一部を失うことになります。ご指摘のとおり、Carbonは64ビットに移植されません。 QtはCarbon APIに実装されているため、Trolltech/NokiaはQtをCocoa APIに移植して64ビット互換にする必要がありました。私の理解では、Qtの次のリリース(現在 release candiate で)はこの移行を完了し、OS Xで64ビット互換です。あなたはQt 4.5のソースを見てみたいかもしれません'C++とCocoa APIの統合に興味があります。


while Appleはしばらくの間、Cocoa APIをJavaで使用できるようにしましたが、ブリッジは広範な手動調整を必要とし、上記のKey-Valueバインディングなどのより高度なテクノロジーを処理できませんでした。現在、Python、Rubyなどの動的に型指定されたランタイムバインド言語は、Objective-CなしでCocoaアプリを作成するための唯一の本当のオプションです(もちろん、これらのブリッジは内部でObjective-Cを使用します)。

110
Barry Wark

馬鹿げているように聞こえるかもしれませんが、実際にはMac OS X用のGUIを作成するために純粋なC++コードを書くことができますが、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;
}
65
FX. J. Adi Lima

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

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

17
fhe

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

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

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

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

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

RealmでホストされているPeter Steinbergerによる素晴らしいビデオがあります [Objective] C++:何が間違っている可能性がありますか? まだObjective-C++を使用している人に強くお勧めします。

9
Andy Dent

単純なVanilla 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ファイルがある場合に便利です。

4
Matt Stevens

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

CocoaクラスのC++ラッパーを作成しようとしました です。

とてもいい経験でした。 C++はObjective-Cよりも優れたタイプセーフティを提供し、コードの記述を減らしました。しかし、コンパイル時間とメモリの安全性はさらに悪くなります。可能ですが、一部の動的ベースの機能は簡単に処理できませんでした。 C++で処理するのは意味がないと思います。

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

1
Eonil

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

0
milesmeow