我可以在同一个 Xcode 项目中拥有 Swift、Objective-C、C 和 C++ 文件吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32541268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:10:34  来源:igfitidea点击:

Can I have Swift, Objective-C, C and C++ files in the same Xcode project?

c++objective-ccswiftbridging-header

提问by SwiftArchitect

Can all 4 languages be used in the same project at all, and if so how?

是否可以在同一个项目中使用所有 4 种语言,如果可以,如何使用?

There are similarquestions in the flavor: Can I mix Swift with C++? Like the Objective - C .mm filesto which the accepted answer is no.

风味中也有类似的问题:我可以将 Swift 与 C++ 混合使用吗?就像接受答案是否定的 Objective-C .mm 文件一样

Using Bridging Headeradequately, .hthat do not contain C++statements, Objective-Cwrappers when .hdo contain C++, .mmfiles to do the actual wrapping of C++classes, and .swift, can the 4 languages (5 if you include Objective-C++) build and link into a single executable?

利用Bridging Header充分,.h不包含C++报表,Objective-C包装时.h不包含C++.mm文件做实际的包装C++类和.swift,可以在4种语言(5如果包括Objective-C++)构建和链接成一个单一的可执行文件?



objective-c++xcode

目标 C++ xcode

回答by SwiftArchitect

YES.

是的。

You can mix Swift, C, C++, Objective-C& Objective-C++files in the same Xcode project.

您可以在同一个 Xcode 项目中混合使用Swift, C, C++, Objective-C&Objective-C++文件。

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++

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 for C++

用于 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

目标-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++

目标-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

Bridging-Header.h

Cannot import CPP.hppheader file, not because of it's naming convention, but because it contains the classkeyword.

无法导入CPP.hpp头文件,不是因为它的命名约定,而是因为它包含class关键字。

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

Invocation from Swift

从 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 (Headers)

.h(标题)

(See item 3in this Stack Overflow answer)

(见第3项这个堆栈溢出的答案

.h: this is the tricky part, since they are ambiguously used for all flavors of C, ++ or not, Objective or not. When a .h does not contain a single C++ keyword, like class, it can be added to the ...Bridging-Header.h, and will expose whatever function the corresponding .c or .cpp functionalities it declares. Otherwise, that header must be wrapped in either a pure C or Objective-C API.

.h:这是棘手的部分,因为它们被含糊不清地用于所有类型的 C、++ 与否、Objective 与否。当 .h 不包含单个 C++ 关键字(如 class)时,可以将其添加到 ...Bridging-Header.h 中,并将公开其声明的相应 .c 或 .cpp 功能的任何函数。否则,该标头必须包含在纯 C 或 Objective-C API 中。

Output

输出

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


Comments

注释

Cy-4AH:

Cy-4AH:

Yes. You only need wrap C++into Cor Objective-Cto use in Swift.

是的。您只需要 wrap C++intoCObjective-Cto use in Swift

Tommy

汤米

Indeed, I have a project that does exactly that. C++for the thrust of the abstract cross-platform model stuff with some Cparts underneath; Objective-Cto wrap the C++classes for Swiftpurposes, Swiftto bind all that to a subclass of NSDocument, with some custom views that interrogate the Cstuff.

事实上,我有一个项目就是这样做的。C++为了抽象的跨平台模型的推力,C下面有一些部分;出于目的Objective-C包装C++SwiftSwift将所有这些绑定到 的子类NSDocument,以及一些查询这些C内容的自定义视图。

MaddTheSane

疯疯癫癫

Added the extern "C"wrapper as per your excellent suggestion. To invoke the Cmethod void hello_c(const char * name)from C++method hello_cpp(const std::string& name), add #include "C.h"and call hello_c(name.c_str());.

extern "C"根据您的极好建议添加了包装器。为了调用Ç方法void hello_c(const char * name)C ++方法hello_cpp(const std::string& name),ADD#include "C.h"和呼叫hello_c(name.c_str());

Keith Adler

基思·阿德勒

The new SO-32541268: Now with parameters!

新的SO-32541268:现在用的参数!



? Find this solution on GitHuband additional details on Swift Recipes.

? 在GitHub 上找到此解决方案,在Swift Recipes找到更多详细信息。