web-dev-qa-db-ja.com

SwiftとC ++を混在させることはできますか? Objective-C .mmファイルと同様

.mファイルを.mmに変更し、C++を使用しました。 Swiftで同じことをする方法はありますか?

122
EhTd

いいえ。mから.mmに切り替えると、実際にはObjective-CからObjective-C++と呼ばれる異なる言語(多くの微妙な違いがある)に切り替わります。したがって、実際にはC++を使用していません。入力としてほとんどのC++を受け入れるObjective-C++を使用しています(C++がすべてではなくほとんどのCを入力として受け入れるのと同じ方法で)。まったくC++ではないと言うときは、nilという名前の変数(正当なC++)を含むC++ファイルを検討し、Objective-C++としてコンパイルしてみてください。

Swiftには同じ関係はありません。 CまたはC++のスーパーセットではなく、.Swiftファイルで直接使用することはできません。

"CocoaとObjective-CでSwiftを使用する" も教えてくれます:

C++コードをSwiftに直接インポートすることはできません。代わりに、C++コード用のObjective-CまたはCラッパーを作成します。

107
Rob Napier

混乱は、ファイル拡張子を.mから.mmに変更するだけで、言語を橋渡しするために必要なすべてであるという仮定から生じるかもしれません。 .mmとの摩擦を引き起こすのは.cppではなく、確実に.hヘッダーであってはならないC++ヘッダーです。


同じプロジェクト:はい。

sameプロジェクトでは、CC++Objective-CObjective C++Swift、偶数Assembly.

  1. ...Bridging-Header.hCObjective-CおよびObjective-C++toSwiftこのブリッジを使用
  2. <ProductModuleName>-Swift.hautomaticallyyourSwift@objcでマークされたクラスをに公開しますObjective-C
  3. .h:これは、C++のすべてのフレーバーに曖昧に使用されているため、扱いにくい部分です。 かどうか、目的かどうか。 .hに単一のC++キーワードが含まれていない場合(classなど)、...Bridging-Header.hに追加でき、対応する.cor.cppが宣言する機能。それ以外の場合、そのヘッダーは、純粋なCまたはObjective-CAPI。

同じファイル:いいえ.

sameファイルでは、5つすべてを混在させることはできません。同じソースファイルで:

  1. .Swift:あなたはできませんSwift
  2. .mObjective-CCを混在させることができます。 ( @ Vinzzz
  3. .mmObjective-CC++を混在させることができます。このブリッジはObjective-C++です。 ( @ Vinzzz )。
  4. .c:pureC
  5. .cpp:混在させることができますC++Assembly@ Vality
  6. .h:ユビキタスであいまいCC++Objective-CまたはObjective-C++であるため、答えは依存します。

参照

156
SwiftArchitect

C++、Objective C、およびSwiftコードを混合する方法を示す簡単なXcode 6プロジェクトを作成しました。

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

特に、この例では、SwiftからObjective CおよびC++関数を呼び出します。

重要なのは、共有ヘッダーProject-Bridging-Header.hを作成し、そこにObjective Cヘッダーを配置することです。

完全な例としてプロジェクトをダウンロードしてください。

72

Swift、Objective-C、C++を使用して、ちょっとしたサンプルプロジェクトを作成しました。これは、iOSでOpenCVステッチを使用する方法のデモです。 OpenCV APIはC++なので、Swiftから直接話をすることはできません。実装ファイルがObjective-C++である小さなラッパークラスを使用します。 HeaderファイルはクリーンなObjective-Cなので、Swiftはこれと直接やり取りできます。 Swiftが対話するヘッダーにC++風のファイルを間接的にインポートしないように注意する必要があります。

プロジェクトはこちら: https://github.com/foundry/OpenCVSwiftStitch

27
foundry

また、Objective-Cをスキップファイルを間に入れることもできます。 Cヘッダーファイルと.cppソースファイルを追加するだけです。ヘッダーファイルにはC宣言のみを含め、ソースファイルにはC++コードを含めます。次に、Cヘッダーファイルを**-Bridging-Header.hに含めます。

次の例は、C++オブジェクト(struct Foo)へのポインターを返すため、Swiftは、グローバルスペースでstruct Fooを定義する代わりにCOpaquePointerに格納できます。

Foo.hファイル(Swiftで表示-ブリッジングファイルに含まれています)

#ifndef FOO_H
#define FOO_H

// Strictly C code here.
// 'struct Foo' is opaque (the compiler has no info about it except that 
// it's a struct we store addresses (pointers) to it.
struct Foo* foo_create();
void foo_destroy(struct Foo* foo);

#endif

内部ソースファイルFoo.cpp(Swiftには表示されません):

extern "C"
{
#include "Foo.h"
}
#include <vector>

using namespace std;

// C++ code is fine here. Can add methods, constructors, destructors, C++ data members, etc.
struct Foo
{
   vector<int> data;
};

struct Foo* foo_create()
{
   return new Foo;
}

void foo_destroy(struct Foo* foo)
{
    delete foo;
}
25
Dan G

C++/Swift通信を自動化するclangツールでの私の試みは次のとおりです。 SwiftからC++クラスをインスタンス化し、C++クラスから継承し、Swiftの仮想メソッドをオーバーライドすることもできます。
エクスポートするC++クラスをSwiftに解析し、Objective-C/Objective-C++ブリッジを自動的に生成します。

https://github.com/sandym/swiftpp

13
Sandy

SwiftはC++と直接互換性がありません。この問題を回避するには、C++コードをObjective-Cでラップし、SwiftでObjective Cラッパーを使用します。

8
Austin

Opencvを組み合わせたSwiftのデモプログラムもあります。

https://github.com/russj/Swift_opencv3_demo からダウンロードできます。

デモの詳細情報 http://flopalm.com/opencv-with-Swift/

4
Russj

いいえ、単一のファイルではありません。

ただし、静的ライブラリまたはフレームワークを必要とせずに、SwiftプロジェクトでC++を使用できます。他の人が言ったように、重要なのは、extern "C" {}トリック。

ビデオチュートリアル: https://www.youtube.com/watch?v=0x6JbiphNS4

4
James Mart

(多くの)1つのトリックは

ブリッジングobj-c ++ファイルにはseparateヘッダーが必要です...

通常、同じ.mmファイルで@interfaceと@implementationをスローすることはできません。

だからあなたのブリッジングヘッダーファイルには

#import "Linkage.hpp"

Linkage.hppにはLinkageの@interfaceがあり、Linkage.mmには.mmの@implementationがあります

その後

...実際にdo n't#Linkage.hppに「yourCpp.hpp」を含めます。

Linkage.mmファイルには#include "yourCpp.hpp"のみを入れ、Linkage.hppファイルにはnotを入れます。

多くのオンラインの例/チュートリアルでは、多くの場合と同様に、ライターは単に@interfaceと@implementationを同じ.mmファイルに配置します。

これは非常に単純なcppブリッジングの例では機能しますが、

問題は:

yourCpp.hppにc ++の機能が確実に備わっている場合(最初の行#include <something>など)、プロセスは失敗します。

しかしdo n'tリンケージに#include "yourCpp.hpp"がある場合header file(.mmファイルに含めることは問題ありません。明らかに必要です)-動作します。

繰り返しになりますが、残念なことに、これはプロセス全体の1つのヒントにすぎません。

2
Fattie

他の答えはわずかに不正確です。実際には、Swiftと[Objective-] C [++]の両方を同じファイルに混在させることができますが、期待する方法ではありません。

このファイル(c.Swift)は、swiftc c.Swiftclang -x objective-c c.Swiftの両方で有効な実行可能ファイルにコンパイルされます

/* /* */
#if 0
// */
import Foundation
print("Hello from Swift!")
/* /* */
#endif
#include <stdio.h>
int main()
{
    puts("Hello from C!");
    return 0;
}
// */
2
snake5

これが誰にとっても役立つ場合、簡単なSwiftコマンドラインユーティリティから簡単なC++静的ライブラリを呼び出す簡単なチュートリアルもあります。これは、コードの概念を証明する非常に簡単なものです。

Objective-Cは関与せず、SwiftとC++のみが関与します。 C++ライブラリのコードは、extern "C"リンケージを持つ関数を実装するC++ラッパーによって呼び出されます。その関数は、ブリッジングヘッダーで参照され、Swiftから呼び出されます。

http://www.swiftprogrammer.info/Swift_call_cpp.html を参照してください

1
Anatoli P

公式リソースの SE-0038 へのリンクを提供しています。と記述されています。これにより、Swiftプログラミング言語。

今日のステータスは、これが受け入れられたがまだスケジュールされていない機能要求であることです。

このリンクは、この機能を探している人を正しい方向に導くことを目的としています。

1
Ryan Heitner