可以在同一项目中完全使用所有4种语言吗?
这个风格也有类似的问题:我可以将Swift与C ++混合使用吗?类似于 Objective-C .mm文件,对于该文件,可接受的答案 为否。
Bridging Header适当地使用.h不包含C语句的语句, Objective-C何时.h包含的包装器C,.mm用于 实际包装C类的文件以及.swift,这4种语言(如果 包含,则为5种Objective-C)能否构建并链接到单个可执行文件中?
您可以混合使用Swift,C,C++,Objective-C和Objective-C++中的文件相同的Xcode项目。
Swift
C
C++
Objective-C
Objective-C++
Xcode
// 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); }
// 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; }
// 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
// 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
// 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") }
Cannot importCPP.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"
// 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")
(See item 3 in this Stack Overflow answer)
.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.
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.
Tommy
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.
NSDocument
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());.
extern "C"
void hello_c(const char * name)
hello_cpp(const std::string& name)
#include "C.h"
hello_c(name.c_str());
Keith Adler
The newSO-32541268: Now with parameters!
► Find this solution on GitHub and additional details on Swift Recipes.