Can all 4 languages be used in the same project at all, and if so how?
所有4种语言都可以在同一个项目中使用吗?
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.
味道中也有类似的问题:我能把Swift和c++混在一起吗?就像Objective - C .mm文件一样,接受的答案是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?
充分使用桥接头、不包含c++语句的.h、当.h包含c++时的Objective-C包装器、用于实际包装c++类的.mm文件和.swift,这四种语言(如果包含Objective-C++)能否构建并链接到单个可执行文件中?
objective - c + + xcode
1 个解决方案
#1
92
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
// 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;
}
Objective-C wrapper for 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
Objective-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
Cannot import CPP.hpp
header file, not because of it's naming convention, but because it contains the class
keyword.
不能导入CPP。hpp头文件,不是因为它的命名约定,而是因为它包含类关键字。
#import "C.h"
#import "CPP-Wrapper.h"
#import "Objective-C.h"
#import "Objective-CPP.h"
Invocation from 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)
(See item 3 in 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、+或not、Objective或not中都有含糊的用法。当.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:
Yes. You only need wrap C++
into C
or Objective-C
to use in Swift
.
是的。您只需要将c++包装成C或Objective-C就可以在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将所有这些绑定到NSDocument的子类,并使用一些自定义视图来查询C内容。
MaddTheSane
Added the extern "C"
wrapper as per your excellent suggestion. To invoke the C method 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());
.
根据你的优秀建议添加外包装“C”包装。要从c++方法hello_cpp(const std::string& name)调用C方法void hello_c(const char * name),添加#include“C”。h”和调用hello_c(name.c_str());。
基思•阿德勒
The new SO-32541268: Now with parameters!
新的SO-32541268:现在有了参数!
► Find this solution on GitHub and additional details on Swift Recipes.
►GitHub上找到这个解决方案和额外的细节迅速食谱。
#1
92
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
// 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;
}
Objective-C wrapper for 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
Objective-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
Cannot import CPP.hpp
header file, not because of it's naming convention, but because it contains the class
keyword.
不能导入CPP。hpp头文件,不是因为它的命名约定,而是因为它包含类关键字。
#import "C.h"
#import "CPP-Wrapper.h"
#import "Objective-C.h"
#import "Objective-CPP.h"
Invocation from 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)
(See item 3 in 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、+或not、Objective或not中都有含糊的用法。当.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:
Yes. You only need wrap C++
into C
or Objective-C
to use in Swift
.
是的。您只需要将c++包装成C或Objective-C就可以在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将所有这些绑定到NSDocument的子类,并使用一些自定义视图来查询C内容。
MaddTheSane
Added the extern "C"
wrapper as per your excellent suggestion. To invoke the C method 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());
.
根据你的优秀建议添加外包装“C”包装。要从c++方法hello_cpp(const std::string& name)调用C方法void hello_c(const char * name),添加#include“C”。h”和调用hello_c(name.c_str());。
基思•阿德勒
The new SO-32541268: Now with parameters!
新的SO-32541268:现在有了参数!
► Find this solution on GitHub and additional details on Swift Recipes.
►GitHub上找到这个解决方案和额外的细节迅速食谱。