c++ - 我可以使用 Swift Package Manager 在同一个 swift 包中混合 C++ 和 Swift 吗?

我想用 C++ 编写一个模块,并用 C 编写一些可在 Swift 中访问的函数。

我有点困惑,因为无论我做什么,SPM 都坚持尝试编译 C++ 代码,就好像它是 Objective-C 一样,当然它找不到正确的头文件。

这是我的尝试。

源码目录结构:

Sources
|
+-CxxModule
| |
| +-include
| | |
| | +-CxxModule.hpp
| |
| +-CxxModule.cpp
|
+-SwiftModule
  |
  +-SwiftModule.swift

清单 Package.swift 如下:

// swift-tools-version: 5.6

import PackageDescription

let package = Package(
    name: "CxxLibrary",
    products: [
        .library(
            name: "CxxLibrary",
            targets: ["SwiftModule"]),
    ],
    dependencies: [
    ],
    targets: [
        .target(
            name: "CxxModule",
            dependencies: []),
        .target(
            name: "SwiftModule",
            dependencies: ["CxxModule"],
            path: "Sources/SwiftModule"
        ),
    ]
)

CxxModule.hpp 如下:

#ifndef CxxModule_hpp
#define CxxModule_hpp

#include <iostream>

extern "C" void printHello();

#endif /* CxxModule_hpp */

CxxModule.cpp 如下:

#include "CxxModule.hpp"

void printHello() {
    // use something from the standard library to make sure
    // c++ is really being used
    std::cout << "Hello, world!" << std::endl;
}

最后,SwiftModule.swift

import CxxModule

我错过了什么?有没有办法告诉 SPM 该模块应该在 C++ 中?还是目前根本不受支持?

注意:如果我消除 Swift 目标,C++ 编译得很好。

回答1

我能够解决这个问题。答案是“是”,只要暴露于 Swift 的标头在纯 C 中是可读的。

首先,我将所有 C++ 特定代码(尤其是引用标准库的头文件)移动到源 cpp 文件中:

#include <iostream>
#include "CxxModule.hpp"

void printHello() {
    // use something from the standard library to make sure
    // c++ is really being used
    std::cout << "Hello, world!" << std::endl;
}

其次,我添加了宏以使标头在 C 和 C++ 中都可读:

#ifndef CxxModule_hpp
#define CxxModule_hpp

#ifdef __cplusplus
extern "C" {
#endif

void printHello();

#ifdef __cplusplus
}
#endif

#endif /* CxxModule_hpp */

文件结构和 Swift 模块保持不变。

教训:任何将被 C++ 和 Swift 读取的标头都必须被两者读取。 (Swift 能够理解 C 头文件,但不能理解 C++ 头文件,至少在当前状态下是这样。)

相似文章

随机推荐

最新文章