65

同じプロジェクトで 4 つの言語すべてを使用できますか?

フレーバーにも同様の質問があります: Swift と C++ を混在させることはできますか? 受け入れられた答えがnoである Objective-C .mm ファイルのように。

ステートメントを含まないラッパーをBridging Header適切に使用して、クラスの実際のラッピングを行うファイル、およびを含む場合、4 つの言語 (を含める場合は 5 つ) をビルドして単一の実行可能ファイルにリンクできますか?.hC++Objective-C.hC++.mmC++.swiftObjective-C++


4

1 に答える 1

145

はい。

Swift、、、およびファイルを同じ Xcode プロジェクトにC混在させることができます。C++Objective-CObjective-C++

C

// Declaration: C.h
#ifndef C_h
#define C_h
#ifdef __cplusplus
extern "C" {
#endif
    void hello_c(const char * name);
#ifdef __cplusplus
}
#endif
#endif /* C_h */

// Definition: C.c
#include "C.h"
#include <stdio.h>
void hello_c(const char * name) {
    printf("Hello %s in C\n", name);
}

C++

// Declaration: CPP.hpp
#pragma once
#include <string>
class CPP {
public:
    void hello_cpp(const std::string& name);
};

// Definition: CPP.cpp
#include "CPP.hpp"
#include <iostream>
using namespace std;
void CPP::hello_cpp(const std::string& name) {
    cout << "Hello " << name << " in C++" << endl;
}

C++ 用の Objective-C ラッパー

// Declaration: CPP-Wrapper.h
#import <Foundation/Foundation.h>
@interface CPP_Wrapper : NSObject
- (void)hello_cpp_wrapped:(NSString *)name;
@end

// Definition: CPP-Wrapper.mm
#import "CPP-Wrapper.h"
#include "CPP.hpp"
@implementation CPP_Wrapper
- (void)hello_cpp_wrapped:(NSString *)name {
    CPP cpp;
    cpp.hello_cpp([name cStringUsingEncoding:NSUTF8StringEncoding]);
}
@end

Objective-C

// Declaration: Objective-C.h
#import <Foundation/Foundation.h>
@interface Objective_C : NSObject
- (void)hello_objectiveC:(NSString *)name;
@end

// Definition: Objective-C.m
#import "Objective-C.h"
@implementation Objective_C
- (void)hello_objectiveC:(NSString*)name {
    printf("Hello %s in Objective-C\n", [name cStringUsingEncoding:NSUTF8StringEncoding]);
}
@end

Objective-C++

// Declaration: Objective-CPP.h
#import <Foundation/Foundation.h>
@interface Objective_CPP : NSObject
- (void)hello_objectiveCpp:(NSString *)name;
@end

// Definition: Objective-CPP.mm
#include <iostream>
#import "Objective-CPP.h"
using namespace std;
@implementation Objective_CPP
- (void)hello_objectiveCpp:(NSString *)name {
    cout << "Hello " << [name cStringUsingEncoding:NSUTF8StringEncoding] << " in Objective-C++\n";
}
@end

迅速

// Declaration & definition: Swift.swift
func hello_swift(_ name: String) {
    print("Hello \(name) in Swift")
}

ブリッジング-Header.h

CPP.hpp命名規則のためではなく、classキーワードが含まれているため、ヘッダー ファイルをインポートできません。

#import "C.h"
#import "CPP-Wrapper.h"
#import "Objective-C.h"
#import "Objective-CPP.h"

Swift からの呼び出し

// Invoke C
hello_c("World".cStringUsingEncoding(NSUTF8StringEncoding))

// Can't Invoke C++ without a wrapper
// CPP().hello_cpp("World".cStringUsingEncoding(NSUTF8StringEncoding))
// Invoke C++ through Objective-C
CPP_Wrapper().hello_cpp_wrapped("World")

// Invoke Objective-C
Objective_C().hello_objectiveC("World")

// Invoke Objective-C++
Objective_CPP().hello_objectiveCpp("World")

// Invoke Swift
Swift().hello_swift("World")

.h (ヘッダー)

(このスタック オーバーフローの回答の項目 3を参照してください)

.h: C のすべてのフレーバー、++ かどうか、Objective かどうかであいまいに使用されるため、これは注意が必要な部分です。.h に class などの C++ キーワードが 1 つも含まれていない場合、それを ...Bridging-Header.h に追加することができ、宣言されている対応する .c または .cpp 機能のすべての関数を公開します。それ以外の場合、そのヘッダーは純粋な C または Objective-C API でラップする必要があります。

出力

Hello World in C
Hello World in C++
Hello World in Objective-C
Hello World in Objective-C++
Hello World in Swift

コメント

Cy-4AH :

はい。にラップC++するCObjective-C、 で使用するだけですSwift

トミー

実際、私はまさにそれを行うプロジェクトを持っています。いくつかの部分が下C++にある抽象的なクロスプラットフォームモデルのものの推力のために。目的のためにクラスをラップし、それらすべてを のサブクラスにバインドし、それらを問​​い合わせるいくつかのカスタム ビューを使用します。CObjective-CC++SwiftSwiftNSDocumentC

マッドザセイン

extern "C"あなたの優れた提案に従ってラッパーを追加しました。C++メソッドからCメソッドを呼び出すには、 を追加して呼び出します。void hello_c(const char * name)hello_cpp(const std::string& name)#include "C.h"hello_c(name.c_str());

キース・アドラー

新しいSO-32541268 : パラメータ付きになりました!


GitHubでこのソリューションを見つけ、 Swift Recipesで追加の詳細を見つけてください。

于 2015-09-13T06:16:38.190 に答える