65

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

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

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?


4

1 回答 1

145

是的。

您可以在同一个 Xcode 项目中混合Swift, C, C++, Objective-C&文件。Objective-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++

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

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

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

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

迅速

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

桥接-Header.h

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

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

从 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(标题)

(请参阅此 Stack Overflow 答案中的第 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

是的。您只需要 wrap C++intoCObjective-C使用 in Swift

汤米

事实上,我有一个项目正是这样做的。C++用于抽象跨平台模型的推力,下面有一些C部分;出于某种目的Objective-C包装C++类,将所有这些绑定到 的子类,并带有一些询问这些东西的自定义视图。SwiftSwiftNSDocumentC

疯疯癫癫

extern "C"根据您的出色建议添加了包装器。要从C++方法调用C方法,请添加并调用.void hello_c(const char * name)hello_cpp(const std::string& name)#include "C.h"hello_c(name.c_str());

基思·阿德勒

SO-32541268:现在带有参数!


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

于 2015-09-13T06:16:38.190 回答