我可以在同一个 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
Can I have Swift, Objective-C, C and C++ files in the same Xcode project?
提问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 Header
adequately, .h
that do not contain C++
statements, Objective-C
wrappers when .h
do contain C++
, .mm
files 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++
)构建和链接成一个单一的可执行文件?
回答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.hpp
header file, not because of it's naming convention, but because it contains the class
keyword.
无法导入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
注释
Yes. You only need wrap C++
into C
or Objective-C
to use in Swift
.
是的。您只需要 wrap C++
intoC
或Objective-C
to use in Swift
。
Indeed, I have a project that does exactly that. C++
for the thrust of the abstract cross-platform model stuff with some C
parts underneath; Objective-C
to wrap the C++
classes for Swift
purposes, Swift
to bind all that to a subclass of NSDocument
, with some custom views that interrogate the C
stuff.
事实上,我有一个项目就是这样做的。C++
为了抽象的跨平台模型的推力,C
下面有一些部分;出于目的Objective-C
包装C++
类Swift
,Swift
将所有这些绑定到 的子类NSDocument
,以及一些查询这些C
内容的自定义视图。
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());
。
The new SO-32541268: Now with parameters!
在新的SO-32541268:现在用的参数!
? Find this solution on GitHuband additional details on Swift Recipes.
? 在GitHub 上找到此解决方案,在Swift Recipes上找到更多详细信息。