我可以在同一个Xcode项目中使用Swift,Objective-C,C和C++文件吗?

Swi*_*ect 61 c c++ objective-c swift bridging-header

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

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

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


Swi*_*ect 120

是.

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

Objective-C 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

目标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
Run Code Online (Sandbox Code Playgroud)

迅速

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

转职Header.h

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

#import "C.h"
#import "CPP-Wrapper.h"
#import "Objective-C.h"
#import "Objective-CPP.h"
Run Code Online (Sandbox Code Playgroud)

从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")
Run Code Online (Sandbox Code Playgroud)

.h(标题)

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

.h:这是一个棘手的部分,因为它们被模糊地用于所有C,++或不同的目标,无论是否.当.h不包含单个C++关键字(如类)时,它可以添加到... 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
Run Code Online (Sandbox Code Playgroud)

评论

Cy-4AH:

是.你只需换C++CObjective-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上找到此解决方案以及有关Swift Recipes的其他详细信息.

  • +1 - 令人惊讶的答案,但真正的耻辱是简单的C++方法没有将指针或引用另一个C++对象作为参数 - 这就是我正在做的事情. (4认同)
  • @SwiftArchitect绝对是一个很好的例子,但是我认为如果在目标c ++包装程序的.h文件中包含&lt;vector&gt;或&lt;iostream&gt;,它将对我不起作用 (2认同)
  • @SwiftArchitect这仍然有效吗?`#include &lt;string&gt;`在CPP.hpp中产生以下错误`'string'file not found`。 (2认同)
  • @SwiftArchitect 我明白我的问题是什么了。我将“CPP-Wrapper”命名为 .m 而不是 .mm 您可能希望将“C++ 的 Objective-C 包装器”标题更改为“C++ 的 Objective-C++ 包装器”。即使注释中的文件名以 .mm 结尾,如果有人(像我一样)创建了 .m,那么 `#include &lt;string&gt;` 会在 CPP.hpp 中产生以下错误“'string' file not find”。感谢这个伟大的资源。:-) (2认同)