gpt4 book ai didi

c++ - 如何在另一个模块或 Xcode 项目中包含 Swift 包中的 C++ 模块

转载 作者:行者123 更新时间:2023-12-05 03:40:52 25 4
gpt4 key购买 nike

总结:在创建包含 C++ 模块和 Obj-C 模块的 Swift 包时,C++ header 导入出现问题。

这里的模块或“客户端”中没有涉及 Swift 代码 - 这只是关于使用 Swift 包管理器来创建和使用模块。在过去使用框架时,我经常使用来自 Objective-C 客户端(以及 Swift 代码使用的 Objective-C 包装器)的 C++ 代码。

我正在尝试使用 Swift 包管理器创建一个包含 C++ 和 Objective-C API 的包。我有一个 Swift 包,带有工作单元测试,结构如下:MyPackageCPP是一个C++实现; MyPackage是围绕它的 Objective-C 包装器。

Package.swift 文件是

import PackageDescription

let package = Package(
name: "MyPackage",
platforms: [.iOS(.v13)],
products: [
.library(name: "MyPackageCPP", targets: ["MyPackageCPP"]),
.library(name: "MyPackage", targets: ["MyPackage"]),
],
targets: [
.target(
name: "MyPackageCPP",
path: "Sources/MyPackageCPP",
publicHeadersPath: "include"
),
.target(
name: "MyPackage",
dependencies: ["MyPackageCPP"],
path: "Sources/MyPackage",
exclude: [
"Info.plist",
],
publicHeadersPath: "include"
),
.testTarget( // C++ tests
name: "MyPackageCPPTests",
dependencies: ["MyPackageCPP"]
),
.testTarget( // Obj-C wrapper tests
name: "MyPackageTests",
dependencies: ["MyPackage"]
)
],
cxxLanguageStandard: .gnucxx1z
)

目录结构为

MyPackage
|
.- Sources
| |
| .- MyPackage
| | |
| . .- Classes (implementation files for Objective-C wrappers)
| | |
| | .- include
| | MyClass.h (Obj-C header)
| |
| .- MyPackageCPP
| |
| .- Classes (C++ Implementation files)
| |
| .- include
| MyClassCPP.h (C++ header)
| MyPointClass.h (Simple C-header defining a custom struct)
|
.- Tests
|
.- MyPackageCPPTests
| MyPackageCPPTests.mm (XCTestCase-based unit tests for C++ API)
|
.- MyPackageTests
MyPackageTests.mm (XCTestCase-based unit tests for pure Obj-C API)

关键头文件:

MyPointClass.h(旨在定义一个 C++ 类及其 Obj-C 包装器均可使用的简单 C 类型):

struct MyPoint {
double x;
double y;
};

MyClassCPP.h:

#pragma once

#include "MyPointClass.h"

#include <string>
#include <memory>

class MyClassCPP {

public:
MyClassCPP() = delete;
MyClassCPP(const std::string &info);
~MyClassCPP();

bool initialized();
MyPoint modifyPoint(MyPoint point);


private:
struct Impl;
std::unique_ptr <struct Impl> _pImpl;
};

MyClass.h(Obj-C 包装类)

#import <UIKit/UIKit.h>

#import "MyPointClass.h"

NS_ASSUME_NONNULL_BEGIN

// iOS Platform specific implementation

@interface MyClass : NSObject

-(instancetype)initWithInfoInAString:(NSString*)someInfoInAString;

-(MyPoint)modifyPoint:(MyPoint)point;

@property (atomic, readonly) BOOL initialized;

@end

NS_ASSUME_NONNULL_END

问题

我一直对包含有问题。单元测试按现在的方式工作,但如果我将 Obj-C 测试文件从 MyPackageTests.mm 更改为至 MyPackageTests.m , 我遇到构建失败 'string' not found.我知道需要 Objective-C++ (*.mm) 才能正确构建使用 C++ 的 Objective-C 文件,但 MyPackageTests 的直接包含链不包含任何 C++。相反,从错误中可以看出,在构建模块时 Obj-C MyPackage , 所有 来自 C++ 包的头文件 MyPackageCPP包括在内,即使只有 C 头文件 MyPointClass.h明确包含在 Obj-C MyPackage 中(通过 #import "MyClass.h" )(线索是“In file included from <module-includes> ”)

当我尝试将 Obj-C 模块包含到简单的 Objective-C 测试应用程序中时,我遇到了相同的构建错误 MyApp导入 Obj-C 包装器 MyPackage :

While building module 'MyPackage' imported from /Users/{user}/TestCode/MyPackage/Tests/MyPackageTests/MyPackageTests.m:3:
While building module 'MyPackageCPP' imported from /Users/{user}/TestCode/MyPackage/Sources/MyPackage/include/MyClass.h:3:
In file included from <module-includes>:1: /Users/{user}/TestCode/MyPackage/Sources/MyPackageCPP/include/MyClassCPP.h:5:10: fatal error: 'string' file not found
#include <string>

问题

C++ 包中的所有 header 是否都必须包含在 Obj-C 包装器构建中? (我曾尝试将 MyClassCPP.h 添加到目标 MyPackage 的排除项中,但无济于事。)或者有没有一种方法可以让我在构建 Obj-C 时仅包含 C++ 包中的纯 C header wrapper MyPackage (同时保持 C++ header 对 C++ 客户端可用)?

最佳答案

is there a way around this that will allow me to include only the pure C-headers from the C++ package, when building the Obj-C wrapper MyPackage (while keeping the C++header available for C++ clients)?

在尝试了多种方法之后,我找到了一种行之有效的方法。这些变化涉及:

  1. 修改结构文件 MyPointClass.h 如下(我在这里重命名为 MyPackageCommonHeaders.h):

    typedef struct MyPoint {
    double x;
    double y;
    } MyPoint;
  2. 添加仅包含以下内容的文件 MyPackageCommonHeaders.c:

    #include "../include/MyPackageCommonHeaders.h"
  3. 仅为共享 header 创建一个新模块

    MyPackage
    |
    .- Sources
    | |
    | .- MyPackage
    | | |
    | | .- Classes (implementation files for Objective-C wrappers)
    | | |
    | | .- include
    | | MyClass.h (Obj-C header)
    | |
    | .- MyPackageCommonHeaders // NEW MODULE
    | | |
    | | .- Classes (C++ Implementation files)
    | | MyPackageCommonHeaders.c // NEW FILE
    | | |
    | | .- include
    | | MyPackageCommonHeaders.h (Simple C-header)
    | |
    | .- MyPackageCPP
    | |
    | .- Classes (C++ Implementation files)
    | |
    | .- include
    | MyClassCPP.h (C++ header)
    |
    .- Tests
    |
    .- MyPackageCPPTests
    | MyPackageCPPTests.mm (XCTestCase-based unit tests for C++ API)
    |
    .- MyPackageTests
    MyPackageTests.m (XCTestCase-based unit tests for pure Obj-C API)

(注意 MyPackageTests.m 不再是 Obj-C++,这是我最初的目标)

  1. 修改 Package.swift 以包含新模块,将其列为 C++ 和 Obj-C API mmodules 的依赖项:

    import PackageDescription

    let package = Package(
    name: "MyPackage",
    platforms: [.iOS(.v13)],
    products: [
    .library(name: "MyPackageCommonHeaders", targets: ["MyPackageCommonHeaders"]),
    .library(name: "MyPackageCPP", targets: ["MyPackageCPP"]),
    .library(name: "MyPackage", targets: ["MyPackage"]),
    ],
    targets: [
    .target(
    name: "MyPackageCPP",
    dependencies: ["MyPackageCommonHeaders"],
    path: "Sources/MyPackageCPP",
    publicHeadersPath: "include"
    ),
    .target(
    name: "MyPackage",
    dependencies: ["MyPackageCPP", "MyPackageCommonHeaders"],
    path: "Sources/MyPackage",
    exclude: [
    "Info.plist",
    ],
    publicHeadersPath: "include"
    ),
    .testTarget( // C++ tests
    name: "MyPackageCPPTests",
    dependencies: ["MyPackageCPP"]
    ),
    .testTarget( // Obj-C wrapper tests
    name: "MyPackageTests",
    dependencies: ["MyPackage"]
    )
    ],
    cxxLanguageStandard: .gnucxx1z
    )

有了这个,我能够创建一个支持 C++ API 的包,以及一个使用 C++ 代码的纯 Obj-C 包装器 API。请注意,Obj-C 包装器不会强制将 Obj-C 调用者提升为 Obj-C++。其中的一个关键部分是一个简单的 C 结构 (MyPoint) 可用于两个 API,因此 Obj-C 包装器不必转换;即,Obj-C 包装器可以返回它从其包装的 C++ 方法中获得的相同对象。

关于c++ - 如何在另一个模块或 Xcode 项目中包含 Swift 包中的 C++ 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67986278/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com