preface

Recently, I learned a set of cross-platform socket package base written by C ++ from the big man, but SWIFT and C ++ cannot call directly, and do not want to write OC, so I transferred to call. Swift can directly call OC and C through the bridge file, and the call to C ++ needs to bridge again

Swift and oc:

  1. Swift, the oc:Swift calls oc need to import the oc header file through the bridge file. There are two ways to create the bridge file:
    • System automatic creation: When creating the OC class in the Swift project, it will prompt you whether to create a bridge file. If you select create, a bridge file named -bridge-header. h will be automatically created
    • Manually create:

      Create a header file:***.hThen look for bridging in Build Settings and set the Objective-C Bridging Header to the created Header file (note the file path).

    Swift (oc); swift (oc); swift (oc);

    The bridge file-Bridging-HeaderIn the.h: #import"Ocperson. h" swift://MARK: swift x oc
    let person = OCPerson(a)let name = person.getName()
    person.printInfo()
    print("oc person name = \(name)")
    Copy the code
  2. Oc the swift,

    Oc calls SWIFT, first of all, it needs to use @objc flag for swift attributes and methods that need to be called by OC, and then it can call all swift classes by importing the generic SWIFT header file, whose name is automatically generated or can be modified by itself. Search in Build Settingsgenerated interface: This is the system’s default swift header, which defaults toProject name – Swift. HIf the project name is Chinese, this will also be Chinese, you can manually modify, after finding the header file, it is recommended to uniformly import the header file in the PCH file, you can call the SWIFT class in oc.
    Swift in the classclass SwiftPerson: NSObject {
        @objc var name = ""
        @objc var age = 0
        @objc var isMale = false
    
        func printInfo(a) {
            print("name = \(name), age = \(age), isMale = \(isMale)")}@objc func getName(a) -> String {
            returnName}} oc:- (void)callSwiftFunc {
        SwiftPerson *person = [[SwiftPerson alloc] init];
        NSString *name = person.name;
        NSLog(@"oc call swiftPerson name = %@, callName = %@", name, [person getName]);
    }
    Copy the code

Swift and c

  1. Swift, the cSwift call c also needs to bridge, just like OC, set the project bridge file first.

    Create c file and header file:
    First_c. H:void printHello(void);
    first_c.c中:
    
    #include "first_c.h"
    
    void printHello(void) {
        printf("hello world ! \n");
    }
    Copy the code

    Then create a secondary bridge header fileCBridging.h, which declares the c function name for swift to call, and the subsequent c function name for swift to call. Then import it in the bridge fileCBridging.hYou can call

    See gitee Demo for code illustration

  2. C calls the swift,C to call swift:
    1. Declare the name of the method c uses to call swift in the secondary bridge file cbridg.h:
    void c_callSwiftFunc(int value);
    Copy the code
    1. In the swift,

    Set the method implementation to NULL in c’s header file:

    void(^ __nonnull c_swiftFuncIMP)(int) = NULL;
    Copy the code
    1. Implement a method in Swift that matches the input and output of the method to be called:
    func c_swiftFuncIMP(value: Int32) -> Void {
        print("c call swift func: \(value)")}Copy the code
    1. Before C calls the swift method, the function to be called refers to swift’s method:
    c_swiftFuncIMP = c_swiftFuncIMP(value:)
    Copy the code
    1. Call this method in C to call the corresponding method in swift:
    void c_callSwiftFunc(int value) {
        c_swiftFuncIMP(value);
    }
    Copy the code

    See gitee Demo for code illustration

Swift and c + +

Swift and OC can be seamlessly called through the bridge file, directly calling C and C ++ is more troublesome, so if you want to call C and C ++ through SWIFT, one method can do the transfer through OC class, packaging C and C ++ in OC, so that SWIFT can call the corresponding C and C ++ related methods by calling OC. Oc can directly call C ++ related methods in the code as long as the.m file is changed to.mm, swift can call C ++ through OC bridge, another method uses SWIFT and C ++ to call each other is to use C packaging, through C packaging to call C ++ methods, The disadvantage is that all call styles become C style, there is no object oriented call like C ++, OC.

  1. Swift call c + + :
    1. Start by creating a c++ class.
    2. In the secondary bridging file CBridging. H, define Pointers to passing c++ objects and declare the c++ functions that need to be called to swift:
    // CPP call correlation
    typedef void* CPPPersonModel;// define C++ object pointer
    
    CPPPersonModel PMCreate(a);CPPPersonModel PMCreateBy(const char *name, int age, int isMale);
    void PMPrintInfo(CPPPersonModel model);
    const char *PMGetName(CPPPersonModel model);
    void PMDestoryModel(CPPPersonModel model);
    void PMCallSwift(CPPPersonModel model, int value);
    Copy the code

    Notice that all of the class’s methods instead pass in a pointer to the calling object as the first argument

    1. Import the header file into the C ++ implementation file (which is why the secondary bridge file is required, since the project header file will have OC-related macros that are not recognized by c or C ++ compilation) and implement these methods:
    CPPPersonModel PMCreate(a) {
        return new CPPPerson(a); }CPPPersonModel PMCreateBy(const char * name, int age, int isMail) {
        return new CPPPerson(name, age, isMail ! =0);
    }
    
    void PMPrintInfo(CPPPersonModel model) {
        CPPPerson *p = (CPPPerson*)model;
        p->printInfo(a); }const char * PMGetName(CPPPersonModel model) {
        CPPPerson *p = (CPPPerson*)model;
        return p->getName(a); }void PMDestoryModel(CPPPersonModel model) {
        CPPPerson *p = (CPPPerson*)model;
        delete p;
    }
    
    void PMCallSwift(CPPPersonModel model, int value) {
        CPPPerson *p = (CPPPerson*)model;
        p->callSwiftFunc(value);
    }
    Copy the code
    1. Call from swift:
    //MARK: swift x cpp
    cpp_swiftFuncIMP = cpp_swiftFuncIMP(value:)
    let p = PMCreateBy("p".33.1)
    let pname = PMGetName(p)
    print("swift call cpp: p = \(String.init(cString: pname!))")
    PMPrintInfo(p)
    PMCallSwift(p, 2222)
    PMDestoryModel(p)
    Copy the code
  2. C ++ call swift: the encapsulation process is similar to the above C call swift, detailed implementation can see demo

The Demo address:

Gitee.com/callmedoby/…

Conclusion:

  • Swift and OC call each other perfectly, swift can also use various dark magic of oc Runtime, but some of swift’s advanced language features: Struct object, high-level enumeration, protocol extension, template, constraint, etc., OC can not be called, SWIFT comes with a high order function (filter, map, etc.), OC does not come with, but can use their own category +block extension implementation.
  • Swift call C needs to introduce the function name through the bridge file can be called, quite convenient, but C call swift is more troublesome, need to specify function implementation in SWIFT
  • Swift calls C ++ in two ways: 1. Through OC encapsulation, 2. Through C encapsulation into C-style methods. Each has its advantages.
  • C ++ calls swift just like C calls swift…

The above is purely personal understanding, if there is any error, welcome to comment, will be the first time to modify, ~~ thank you ~~