wake-up-neo.com

Kann ich Swift-, Objective-C-, C- und C ++ - Dateien im selben Xcode-Projekt haben?

Können alle 4 Sprachen überhaupt im selben Projekt verwendet werden und wenn ja, wie?

Es gibt ähnliche Fragen im Geschmack: Kann ich Swift mit C++ mischen? Wie das Ziel - C .mm files auf die die akzeptierte Antwort lautet no .

Bridging Header Richtig verwenden, .h Die keine C++ - Anweisungen enthalten, Objective-C Wrappen, wenn .hC++ Enthalten, .mm - Dateien für das eigentliche Umbrechen von C++ - Klassen und .Swift - Dateien können in 4 Sprachen (5, wenn Sie Objective-C++ Einschließen) erstellt und verknüpft werden einzelne ausführbare Datei?


Objective-C++Xcode

61
SwiftArchitect

JA.

Sie können Swift, C, C++, Objective-CObjective-C++ Dateien im selben Xcode-Projekt mischen.

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;
}

Objective-C-Wrapper für 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

Ziel 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

Swift

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

Bridging-Header.h

Header-Datei CPP.hpp Kann nicht importiert werden, nicht wegen der Namenskonvention, sondern weil sie das Schlüsselwort class enthält.

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

Aufruf von 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 (Überschriften)

(Siehe Punkt 3 in diese Stapelüberlauf-Antwort )

.h: Dies ist der schwierige Teil, da sie mehrdeutig für alle Varianten von C, ++ oder nicht, Objective oder nicht verwendet werden. Wenn eine .h-Datei kein einzelnes C++ - Schlüsselwort enthält, wie z. B. eine Klasse, kann sie zur ... Bridging-Header.h-Datei hinzugefügt werden und stellt die von ihr deklarierte Funktion der entsprechenden .c- oder .cpp-Funktionen zur Verfügung. Andernfalls muss dieser Header in eine reine C- oder Objective-C-API eingeschlossen werden.

Ausgabe

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

Kommentare

Cy-4AH:

Ja. Sie müssen nur C++ In C oder Objective-C Einwickeln, um es in Swift zu verwenden.

Tommy

In der Tat habe ich ein Projekt, das genau das tut. C++ Für den Schub des abstrakten plattformübergreifenden Modellmaterials mit einigen C Teilen darunter; Objective-C, Um die C++ - Klassen für Swift -Zwecke zu umbrechen, Swift, um all dies mit einigen benutzerdefinierten Ansichten an eine Unterklasse von NSDocument zu binden die das Zeug C abfragen.

MaddTheSane

Der Wrapper extern "C" Wurde gemäß Ihrem ausgezeichneten Vorschlag hinzugefügt. So rufen Sie die [~ # ~] c [~ # ~] -Methode void hello_c(const char * name) von auf C++ Methode hello_cpp(const std::string& name), füge #include "C.h" Hinzu und rufe hello_c(name.c_str()); auf.

Keith Adler

Die new SO-32541268: Jetzt mit Parametern!


► Finden Sie diese Lösung auf GitHub und weitere Details auf Swift Recipes .

118
SwiftArchitect