调用 C++ | Swift

本文最后更新于:2020年12月5日

Swift 不能直接调用 C++,需要通过 Objective-C/C++ 桥接。本文主要介绍了在 Swift 中调用 C++ 的一些技巧。

调用函数

  1. 新建 C++ 文件,勾选生成头文件。
    // CPPFile.hpp
    #include <stdio.h>
    
    class TestCPP {
    public:
        int add(int a, int b);
    };
// CPPFile.cpp
#include "CPPFile.hpp"

int TestCPP::add (int a, int b) {
    return a + b;
}
  1. 新建 Objective-C 文件,此时 Xcode 会提示创建桥接文件,创建即可。这里我们需要调用的是 C++,所以还需要把 .m 文件(Objective-C)改为 .mm 文件(Objective-C++)。然后再新建一个头文件,这样就 Objective-C++ 部分就完成了。相关内容如下:
    // Project-Bridging-Header.h
    #import "OCFile.h"
// OCFile.h
#import <Foundation/Foundation.h>

@interface OCFile : NSObject
+ (int)sumWithNum: (int)a withNum: (int)b;
@end
// OCFile.mm
#import "OCFile.h"
#import "CPPFile.hpp"

@implementation OCFile
+ (int)sumWithNum: (int)a withNum: (int)b {
    int sum = TestCPP.add(a, b)
    return sum;
}
@end

注意

Xcode 默认把 .h 文件当做 Objective-C 而非 Objective-C++ 的头文件,所以在 .h 文件中不可以引用任何 C++ 头文件以及引用了 C++ 头文件的头文件,否则会提示 xxx not found。如果这个无法避免,可以考虑使用 opaque pointers

// CPPClass.h
class CPPClass {
public:
    int getNumber() {
        return 10;
    }
};
// ObjCPP.h
struct CPPMembers;

@interface ObjCPP : NSObject {
    // opaque pointer to store cpp members
    struct CPPMembers *_cppMembers;
}
@end
// ObjCPP.mm
#import "ObjCPP.h"
#import "CPPClass.h"

struct CPPMembers {
    CPPClass member1;
};

@implementation ObjCPP

- (id)init {
    self = [super init];
    if (self) {
        _cppMembers = new CPPMembers;
        NSLog(@"%d", _cppMembers->member1.getNumber());
    }

    return self;
}

- (void)dealloc {
    delete _cppMembers;
}

@end

调用静态库

在 Xcode 编译中引入静态库的思路和 gcc/g++ 等编译器相同:首先需要指定库的名字,其次要指定库的路径。

  1. 指定库的名字:按照下图指示添加想要引入的静态库文件。
  2. 指定库和头文件的路径:在上一步操作的 Build Phases 旁边找到 Build Settings,然后搜索 “Search Paths”,在 Library Search Paths 中添加刚才引入的静态库在本机上的路径。在 Header Search Paths 中添加相应的头文件在本机上的路径。

参考

Swift呼叫C++(圖解版)
How to include C++ headers in an Objective C++ header?