Могу ли я иметь файлы Swift, Objective-C, C и C ++ в одном проекте XCode?

Можно ли вообще использовать все 4 языка в одном проекте, и если да, то как?

Есть аналогичный вопросы в аромате: Могу ли я смешать Swift с C ++? Как Objective — C .mm файлы на который принят ответ нет.

С помощью Bridging Header адекватно, .h которые не содержат C++ заявления, Objective-C обертки, когда .h содержат C++, .mm файлы для фактической упаковки C++ классы и .swift, может 4 языка (5, если вы включите Objective-C++) построить и связать в один исполняемый файл?


53

Решение

Вы можете смешивать Swift, C, C++, Objective-C & Objective-C++ файлы в том же проекте XCode.

// 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);
}
// 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;
}
// 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
// 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
// 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")
}

Невозможно импортировать CPP.hpp Заголовочный файл, не из-за соглашения об именах, а потому что он содержит class ключевое слово.

#import "C.h"#import "CPP-Wrapper.h"#import "Objective-C.h"#import "Objective-CPP.h"
// 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")

(Увидеть пункт 3 в этот ответ переполнения стека)

.h: это сложная часть, так как они неоднозначно используются для всех разновидностей C, ++ или нет, Objective или нет. Когда .h не содержит ни одного ключевого слова C ++, такого как class, его можно добавить в … 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++ в C или же Objective-C использовать в Swift,

Томми

Действительно, у меня есть проект, который делает именно это. C++ для тяги абстрактной кроссплатформенной модели вещи с некоторыми C части внизу; Objective-C обернуть C++ классы для Swift цели, Swift привязать все это к подклассу NSDocumentс некоторыми пользовательскими взглядами, которые опрашивают C вещи.

MaddTheSane

Добавил extern "C" обертка согласно вашему превосходному предложению. Для вызова С метод void hello_c(const char * name) от C ++ метод hello_cpp(const std::string& name), добавлять #include "C.h" и позвонить hello_c(name.c_str());,

Кит Адлер

новый SO-32541268: Теперь с параметрами!


► Найти это решение на GitHub и дополнительные сведения о Свифт Рецепты.

104

Другие решения