Metal Language も C++11 に基づいており、C++ は実績のあるパフォーマンス言語である完全に適合するように思われるため、Objective-C / Swift を完全にバイパスすることを検討しています。私は C++ の分野にとどまりたいと思っています。可能性はありますか?
5 に答える
技術的には可能ですが、それは非常に見苦しく、他の Objective-C の一部を壊してしまう可能性があります。
Objective-C は、C++ と同様に、プリプロセッサとして誕生しました。その遺産の 1 つは、すべての Objective-C メソッドが、オブジェクト インスタンスとメソッド セレクターをそれぞれ最初の 2 つの引数として取り、次に他の宣言された引数を左から右の順序で取る C 関数呼び出しとしても公開されることです。
NSObject
Objective-C ランタイムを形成する と C 呼び出しの両方で、任意のメソッド呼び出しで呼び出される現在のC 関数を検索できます。
したがって、すべての C 関数ポインターを取得する C++ クラスを作成し (C ランタイムからこれを実行して、Objective-C++ ではなく純粋な C++ コードにすることもできます)、そのような適切なコードに直接ジャンプすることができます。
欠点は次のとおりです。Objective-C は通常、動的ディスパッチ (つまり、呼び出しごとに C 関数に解決されるメソッド) を使用し、動的ディスパッチを使用するためにのみ機能するキー値監視などのメカニズムを使用します。他の誰かが監視を開始する前に C 関数ポインターを取得すると、オブザーバーに通知せずにプロパティを更新する呼び出しが行われます。したがって、いくつかのモジュールを壊す可能性があります。
その警告が発行され、より単純な構文のために C++ ブリッジ クラスを Objective-C++ としてビルドできると仮定します。
class MTLArray {
id m_instance;
static NSUInteger (* s_arrayLength)(id object, SEL selector);
};
MTLArray::MTLArray() {
// assuming you use the m_ pattern for instance variables
m_instance = [MTLArray new];
// assuming you use s_ for static variables; also pretending
// the mapping from method to C function will never change —
// KVO is the most prominent exception but otherwise you can
// be exceedingly confident, albeit you'll be relying on
// empirical behaviour, not the formal contract
if(!s_arrayLength) {
s_arrayLength = [MTLArray instanceMethodForSelector:@selector(arrayLength)];
}
}
NSUInteger MTLArray::getArrayLength() {
return s_arrayLength(m_instance, @selector(arrayLength));
}
...ここでは、結果を+instanceMethodForSelector:
適切な型にキャストすることを都合よく断っています。間違っていると確信しているためです。私は、自分の実際のコードに中途半端なものを導入する傾向がありtypedef
ますが、もっと簡潔にした方がよい場合もあります。
Objective-C API を使用したいが、主に C++ で作業する場合は、Objective-C++ が最適です。これは単なる Objective-C ですが、基になる言語として C ではなく C++ を使用しています。
Objective-C クラスを Objective-C++ に変換するには、ソース ファイルのサフィックスを ".m" から ".mm" に変更するだけです。(リンク時に適切な C++ ランタイム ライブラリが含まれていることを確認する必要もあります。)
これを行うと、Objective-C メソッド内で C++ コードを使用できます。これには、std::vector などのテンプレート型や、範囲ベースの for ループなどの C++11 構成体が含まれます。
いいえ。Metal は Objective-C API としてのみ公開されています。せいぜい、Objective-C++ クラスのセットでラップできますが、必要に応じて Objective-C をバイパスする代わりに、オーバーヘッドが追加されるだけです。